package com.youlu.campus.service.activity.impl;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPayConstants;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.activity.service.UserActivityTaskRankingService;
import com.youlu.campus.base.community.RankingList;
import com.youlu.campus.base.interactive.vo.ActivitySignUpRequest;
import com.youlu.campus.base.interactive.vo.ActivityVO;
import com.youlu.campus.common.base.QResult;
import com.youlu.campus.common.exception.BusinessException;

import com.youlu.campus.common.utils.RedisKeyUtil;
import com.youlu.campus.common.utils.ShotUrlUtil;
import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.common.utils.URLUtils;
import com.youlu.campus.entity.ActivityAnswerInfo;
import com.youlu.campus.entity.ActivityCaRule;
import com.youlu.campus.entity.ActivityFeedInfo;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityInfoVo;
import com.youlu.campus.entity.ActivityOrganizerInfo;
import com.youlu.campus.entity.ActivityPlatformConfig;
import com.youlu.campus.entity.ActivityQaInfo;
import com.youlu.campus.entity.ActivityQaRule;
import com.youlu.campus.entity.ActivityQuestionInfo;
import com.youlu.campus.entity.ActivityRecieveRule;
import com.youlu.campus.entity.ActivityRewardRule;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.ActivityTaskRule;
import com.youlu.campus.entity.ActivityUserRecord;
import com.youlu.campus.entity.CaGroupInfo;
import com.youlu.campus.entity.CaInfo;
import com.youlu.campus.entity.CaMaterialConfig;
import com.youlu.campus.entity.CertificateActivityConfig;
import com.youlu.campus.entity.FileExportTask;
import com.youlu.campus.entity.HuoLinkerInfo;
import com.youlu.campus.entity.MemberShipInfo;
import com.youlu.campus.entity.OOrderInfo;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.OrganizerRankingList;
import com.youlu.campus.entity.PayButtonConfigPage;
import com.youlu.campus.entity.PayConfigPage;
import com.youlu.campus.entity.QQMiniUserPO;
import com.youlu.campus.entity.UniversityActivityTaskRanking;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserActivityFootPrint;
import com.youlu.campus.entity.UserActivityPointDetail;
import com.youlu.campus.entity.UserActivityReward;
import com.youlu.campus.entity.UserActivityTaskRankingAttach;
import com.youlu.campus.entity.UserInviteRecord;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.UserParticipateActivityInfo;
import com.youlu.campus.entity.UserParticipateActivityTaskInfo;
import com.youlu.campus.entity.UserPointsDetail;
import com.youlu.campus.entity.UserQaInfo;
import com.youlu.campus.entity.UserWeekActivityTaskRanking;
import com.youlu.campus.entity.VO.RankingListQueryVO;
import com.youlu.campus.entity.VO.req.ActivityFeedQueryVO;
import com.youlu.campus.entity.VO.req.ActivityQaInfoVO;
import com.youlu.campus.entity.VO.req.RankingListResVO;
import com.youlu.campus.entity.VO.req.ReceiveCaVO;
import com.youlu.campus.entity.VO.req.RecieveCaDetailVO;
import com.youlu.campus.entity.VO.req.UserDoQaVO;
import com.youlu.campus.entity.VO.req.UserInviteCreateVO;
import com.youlu.campus.entity.VO.req.UserInviteQueryVO;
import com.youlu.campus.entity.VO.req.UserParticipateActivityInfoQueryVO;
import com.youlu.campus.entity.VO.req.UserQaMqMessageReq;
import com.youlu.campus.entity.VO.res.CaReceiveButtonConfigRes;
import com.youlu.campus.entity.VO.res.CaReceiveConfigRes;
import com.youlu.campus.entity.VO.res.MultiQaRes;
import com.youlu.campus.entity.VO.res.PlatformActivityInfo;
import com.youlu.campus.entity.VO.res.QaInfoScoreResponse;
import com.youlu.campus.entity.VO.res.QaTaskRes;
import com.youlu.campus.entity.VO.res.UserCaInfoRes;
import com.youlu.campus.entity.WechatConfigInfo;
import com.youlu.campus.entity.WechatH5UserPO;
import com.youlu.campus.entity.WechatMiniUserPO;
import com.youlu.campus.entity.ca.GiftCaInfo;
import com.youlu.campus.entity.ca.UserCa;
import com.youlu.campus.entity.commission.DistributorApply;
import com.youlu.campus.entity.commission.DistributorApplyStatusEnum;
import com.youlu.campus.entity.data.DayActivityJoinRecord;
import com.youlu.campus.entity.data.HourActivityJoinRecord;
import com.youlu.campus.entity.domain.ActivityFootPrintDomain;
import com.youlu.campus.entity.domain.ActivityRewadDomain;
import com.youlu.campus.entity.domain.ActivityTaskDataDomain;
import com.youlu.campus.entity.domain.PlayBillDomain;
import com.youlu.campus.entity.domain.RankListDomain;
import com.youlu.campus.entity.domain.ShareBindingDomain;
import com.youlu.campus.entity.domain.UserCaQueryDomain;
import com.youlu.campus.entity.domain.WechatH5PayConfigDomain;
import com.youlu.campus.entity.douyin.DouYinMiniUserPO;
import com.youlu.campus.entity.enums.ShareType;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityPlatformConfigService;
import com.youlu.campus.service.activity.ActivityQaRuleService;
import com.youlu.campus.service.activity.ActivityRecieveRuleService;
import com.youlu.campus.service.activity.ActivityRewardRuleService;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.activity.ActivityTaskRuleService;
import com.youlu.campus.service.activity.ActivityTaskService;
import com.youlu.campus.service.activity.ActivityVideoService;
import com.youlu.campus.service.activity.UserActivityTaskRankingAttachService;
import com.youlu.campus.service.activity.UserParticipateActivityInfoService;
import com.youlu.campus.service.ca.CaInfoService;
import com.youlu.campus.service.ca.CaMaterialConfigService;
import com.youlu.campus.service.ca.UserCaService;
import com.youlu.campus.service.ca.impl.CertificateActivityConfigService;
import com.youlu.campus.service.cache.CacheActivityCaRuleService;
import com.youlu.campus.service.cache.CacheActivityService;
import com.youlu.campus.service.cache.CacheActivityUserRecordService;
import com.youlu.campus.service.cache.CacheCaGroupInfoService;
import com.youlu.campus.service.cache.CacheCaInfoService;
import com.youlu.campus.service.commission.DistributorApplyService;
import com.youlu.campus.service.course.UserActivityService;
import com.youlu.campus.service.data.ActivityDataService;
import com.youlu.campus.service.data.impl.UserQaMQService;
import com.youlu.campus.service.english.ActivityGroupService;
import com.youlu.campus.service.english.CompetitionQaInfoService;
import com.youlu.campus.service.feed.ActivityFeedInfoService;
import com.youlu.campus.service.file.FileExportTaskService;
import com.youlu.campus.service.file.FileService;
import com.youlu.campus.service.invite.UserInviteRecordService;
import com.youlu.campus.service.linker.HuoLinkerInfoService;
import com.youlu.campus.service.organizer.ActivityOrganizerInfoService;
import com.youlu.campus.service.platform.PlatformConfigService;
import com.youlu.campus.service.platform.PointPlatformConfigService;
import com.youlu.campus.service.qa.UserQaInfoService;
import com.youlu.campus.service.qq.QQMiniUserService;
import com.youlu.campus.service.rank.RankBaseService;
import com.youlu.campus.service.rank.RankService;
import com.youlu.campus.service.rank.UserRankListService;
import com.youlu.campus.service.ranking.OrganizerRankingService;
import com.youlu.campus.service.ranking.UniversityActivityRankingService;
import com.youlu.campus.service.ranking.UserActivityPointDetailService;
import com.youlu.campus.service.ranking.UserActivityPointRankingProvinceService;
import com.youlu.campus.service.ranking.UserActivityPointRankingService;
import com.youlu.campus.service.ranking.UserPointRankingService;
import com.youlu.campus.service.ranking.entity.UserActivityPointRanking;
import com.youlu.campus.service.ranking.entity.UserActivityTaskRanking;
import com.youlu.campus.service.university.UniversityService;
import com.youlu.campus.service.utils.WXPayUtil;
import com.youlu.campus.service.visitor.UserPointsService;
import com.youlu.campus.service.visitor.VisitorUserService;
import com.youlu.campus.service.wechat.WechatH5Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.bson.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static com.youlu.campus.base.base.Constants.defaultHead;
import static com.youlu.campus.base.common.Constants.ACTIVITY__V2;

@Slf4j
@Service
public class ActivityServiceImpl implements ActivityService {

    private static final String DEFAULT_UNIVERSITY_LOG = "https://qiniu.gqgood.com/imgfb2fbd3021624202bb1d5386ecb1eb79university-default-logo.jpg";
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private VisitorUserService visitorUserService;

    @Autowired
    private WechatH5Service wechatH5Service;
    @Autowired
    private ActivityOrganizerInfoService activityOrganizerInfoService;
    @Autowired
    private ActivityRewardRuleService activityRewardRuleService;
    @Autowired
    private UniversityService universityService;
    @Autowired
    private ActivityTaskRuleService activityTaskRuleService;
    @Autowired
    private ActivityDataService activityDataService;
    @Autowired
    private ActivityQaRuleService activityQaRuleService;
    @Autowired
    private ActivityRecieveRuleService activityRecieveRuleService;

    @Autowired
    private FileExportTaskService fileExportTaskService;
    @Autowired
    private RankService rankService;
    @Lazy
    @Autowired
    private UserParticipateActivityInfoService userUpInfoService;

    @Autowired
    private PlatformOtherActivityService platformOtherActivityService;

    @Autowired
    private CacheActivityUserRecordService cacheActivityUserRecordService;

    @Autowired
    private CacheActivityCaRuleService cacheActivityCaRuleService;

    @Autowired
    private CacheCaGroupInfoService cacheCaGroupInfoService;
    @Autowired
    private FileService fileService;
    @Autowired
    private CaInfoService caInfoService;

    @Lazy
    @Autowired
    private ActivityPayConfigService activityPayConfigService;
    @Autowired
    private ActivityGroupService activityGroupService;

    @Autowired
    private UserQaMQService userQaMQService;

    @Lazy
    @Autowired
    private UserQaInfoService userQaInfoService;

    @Lazy
    @Autowired
    private DistributorApplyService distributorApplyService;

    @Autowired
    private UserActivityTaskRankingService userActivityTaskRankingService;

    @Value("${sys.defaultHeadUrl}")
    private String defaultHeadUrl;
    @Value("${sys.fileExportPath:/data/file/campus-admin/}")
    private String fileExportPath;

    @Autowired
    private CacheActivityService cacheActivityService;

    @Autowired
    private CacheCaInfoService cacheCaInfoService;

    @Lazy
    @Autowired
    private ActivityPlatformConfigService activityPlatformConfigService;

    @Lazy
    @Autowired
    private UserActivityTaskRankingAttachService userActivityTaskRankingAttachService;
    @Autowired
    private PlatformConfigService platformConfigService;
    @Autowired
    private HuoLinkerInfoService huoLinkerInfoService;
    @Autowired
    private ActivityFeedInfoService activityFeedInfoService;
    private String ORG_RANK_LIST_KEY = "com.luyou.org.rank.acitivityId:%s:taskId:%s";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RedisTemplate<String, String> stringRedisTemplate;

    @Lazy
    @Autowired
    private ActivityTaskService activityTaskService;

    @Autowired
    private UserPointRankingService userPointRankingService;
    @Autowired
    private PointPlatformConfigService pointPlatformConfigService;
    @Autowired
    private UserPointsService userPointsService;
    @Autowired
    private UserInviteRecordService userInviteRecordService;
    @Autowired
    private CertificateActivityConfigService certificateActivityConfigService;
    @Autowired
    private UserCaService userCaService;

    @Autowired
    private UserActivityPointRankingService userActivityPointRankingService;

    @Autowired
    private UserRankListService userRankListService;

    @Autowired
    private UserActivityPointDetailService userActivityPointDetailService;
    @Autowired
    private QQMiniUserService qqMiniUserService;

    @Autowired
    public CompetitionQaInfoService competitionQaInfoService;

    @Autowired
    private UniversityActivityRankingService universityActivityRankingService;
    @Autowired
    private RankBaseService rankBaseService;

    @Autowired
    private UserActivityPointRankingProvinceService userActivityPointRankingProvinceService;
    @Autowired
    private OrganizerRankingService organizerRankingService;
    @Autowired
    private UserActivityService userActivityService;

    @Autowired
    private CaMaterialConfigService caMaterialConfigService;
    @Lazy
    @Autowired
    private ActivityVideoService activityVideoService;

    @Resource(name = "masterMongoTemplate")
    private MongoTemplate masterMongoTemplate;
    /**
     * QQ 小程序活动类型
     */
    public static final String[] QQ_MINI_ACTIVITY_TYPE = new String[]{"qq-mini-plus", "qq-mini-zhongqing-contest", "qq-mini-zhongqing-noncontest"};

    @Override
    public List<ActivityInfo> findAll() {
        Query query = new Query();
        query.addCriteria(Criteria.where("endTime").gte(new Date()));
        query.addCriteria(Criteria.where("otherPlatform").is(Boolean.FALSE));
        return this.mongoTemplate.find(query, ActivityInfo.class);
    }

    @Override

    public Page<ActivityInfo> myActivityList(UserParticipateActivityInfoQueryVO req) {
        log.info(":>>> 我参与的活动列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getUserId())) {
            log.error(":>>> 获取我参与的工作参数错误");
            throw new BusinessException("获取我参与的工作参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("userId").is(req.getUserId()));

        query.addCriteria(Criteria.where("joined").is(Boolean.TRUE));

        if (StringUtils.isNotBlank(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        long count = mongoTemplate.count(query, UserParticipateActivityInfo.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserParticipateActivityInfo> infos = mongoTemplate.find(query.with(pageRequest), UserParticipateActivityInfo.class);
        List<ActivityInfo> activityInfos = new ArrayList<>();

        if (!CollectionUtils.isEmpty(infos)) {
            for (UserParticipateActivityInfo up : infos) {
                Query query1 = new Query().addCriteria(Criteria.where("id").is(up.getActivityId()));
                // 过滤打卡活动
                query1.addCriteria(Criteria.where("taskType").ne(4));
                ActivityInfo activityInfo = mongoTemplate.findOne(query1, ActivityInfo.class);
                if (Objects.nonNull(activityInfo)) {
                    activityInfo.setJoined(up.getJoined());
                    activityInfo.setSignUpTime(up.getSignUpTime());
                    // 状态,0:未开始,1:进行中,2:已完成,3:未完成
                    if (StringUtils.isNotBlank(up.getStatus())) {
                        switch (up.getStatus()) {
                            case "0":
                                activityInfo.setStatus(0);
                                break;
                            case "1":
                                activityInfo.setStatus(1);
                                break;
                            case "2":
                                activityInfo.setStatus(2);
                                break;
                            case "3":
                                activityInfo.setStatus(3);
                                break;
                            default:
                                break;

                        }

                    }

                    activityInfos.add(activityInfo);
                }
            }
        }
        return PageableExecutionUtils.getPage(activityInfos, pageRequest, () -> count);
    }

    // 发现活动列表,用户未参与
    @Override
    public Page<ActivityInfo> list(ActivityVO request) {
        log.info(":>>> 开始获取活动信息:{}", JSON.toJSONString(request));
        if (Objects.isNull(request)) {
            request = new ActivityVO();
        }
        List<String> activityIds = new ArrayList<>();
        Query query = new Query().addCriteria(Criteria.where("userId").is(request.getUerId()));
        List<UserParticipateActivityInfo> infos = mongoTemplate.find(query, UserParticipateActivityInfo.class);
        if (!CollectionUtils.isEmpty(infos)) {
            for (UserParticipateActivityInfo u : infos) {
                if (StringUtils.isNotBlank(u.getActivityId())) {
                    activityIds.add(u.getActivityId());
                }
            }
        }
        log.info(":>>> 用户:{} 参与的活动:{}", request.getUerId(), JSON.toJSON(activityIds));
        List<String> activityPublishedIds = new ArrayList<>();
        if (StringUtils.isNotBlank(request.getPlatform()) && "wechat-mini".equals(request.getPlatform())) {
            List<ActivityPlatformConfig> configs = activityPlatformConfigService.find(request.getPlatform());
            if (!Objects.isNull(configs) && !CollectionUtils.isEmpty(configs)) {
                for (ActivityPlatformConfig config : configs) {
                    if (StringUtils.isNotBlank(config.getActivityId()) && !activityPublishedIds.contains(config.getActivityId())) {
                        activityPublishedIds.add(config.getActivityId());
                    }
                }
            }
        }
        log.info(":>>> 平台:{} 发布的活动活动:{}", request.getPlatform(), JSON.toJSON(activityPublishedIds));
        Query query1 = new Query();
        if (!CollectionUtils.isEmpty(activityPublishedIds)) {
            query1.addCriteria(Criteria.where("id").in(activityPublishedIds));
        }
        // 过滤打卡类的活动
        query1.addCriteria(Criteria.where("taskType").ne(4));
        query1.addCriteria(Criteria.where("deleted").ne(true));
        // 已经发布的活动
//        query1.addCriteria(Criteria.where("published").is(Boolean.TRUE));
        long count = mongoTemplate.count(query1, ActivityInfo.class);
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<ActivityInfo> infos1 = mongoTemplate.find(query1.with(pageRequest), ActivityInfo.class);
        if (Objects.nonNull(infos1) && !CollectionUtils.isEmpty(infos1)) {
            for (ActivityInfo activityInfo : infos1) {
                if (activityIds.contains(activityInfo.getId())) {
                    activityInfo.setJoined(true);
                } else {
                    activityInfo.setJoined(false);
                }
            }
        }
        return PageableExecutionUtils.getPage(infos1, pageRequest, () -> count);
    }

    private String activityInfoUrl = "https://certificatetest.scsc.tech/#/pages/activity-detial?activityId=%s&token=%s";

    @Override
    public Page<ActivityInfoVo> findByPageAndUnfinished(ActivityVO request) {
        log.info(":>>> 开始获取分页活动信息:{}", JSON.toJSONString(request));
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        Query query = new Query();
        //是否获取已经参与的活动
        if (request.getStatus() != null && 1 == request.getStatus()) {
            Date date = new Date();
            query.addCriteria(Criteria.where("startTime").lte(date).and("endTime").gte(date));
        }
        if (request.getStatus() != null && 3 == request.getStatus()) {
            Date date = new Date();
            query.addCriteria(Criteria.where("startTime").gte(date));
        }
        // 过滤打卡类的活动
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, ActivityInfo.class);
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
        Sort sort = Sort.by(Sort.Direction.DESC, "startTime");
        query.with(sort);
        query.with(pageRequest);
        List<ActivityInfo> infoList = mongoTemplate.find(query, ActivityInfo.class);
        long now = System.currentTimeMillis();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        List<ActivityInfoVo> activityInfoVos = new ArrayList<>();
        for (ActivityInfo activityInfo : infoList) {
            ActivityInfoVo activityInfoVo = new ActivityInfoVo();
            activityInfoVo.setId(activityInfo.getId());
            activityInfoVo.setImageUrl(activityInfo.getImageUrl());
            activityInfoVo.setH5Url(String.format(activityInfoUrl, activityInfo.getId(), request.getMinitoken()));
            activityInfoVo.setName(activityInfo.getName());
            activityInfoVo.setDescription(activityInfo.getName());
            String start = sdf.format(activityInfo.getStartTime());
            String end = sdf.format(activityInfo.getEndTime());
            activityInfoVo.setTimeRange(start + "~" + end);

            int status = 2;
            String statusDesc = "已结束";
            if (activityInfo.getStartTime().getTime() <= now && activityInfo.getEndTime().getTime() > now) {
                status = 1;
                statusDesc = "报名中";
            }
            if (activityInfo.getRecieveRewardStartTime() != null && activityInfo.getRecieveRewardStartTime().getTime() <= now && activityInfo.getRecieveRewardEndTime().getTime() > now) {
                status = 1;
                statusDesc = "领取中";
            }
            activityInfoVo.setStatus(status);
            activityInfoVo.setStatusDesc(statusDesc);
            Query query1 = new Query().addCriteria(Criteria.where("activityId").is(activityInfo.getId()));
            Long joinedTotal = userActivityTaskRankingService.count(query1);
            activityInfoVo.setJoinedTotal(joinedTotal + activityInfo.getInitJoinNum());
            activityInfoVos.add(activityInfoVo);
        }
        return PageableExecutionUtils.getPage(activityInfoVos, pageRequest, () -> count);
    }


    @Override
    public Page<ActivityInfoVo> findByPageAndJoined(ActivityVO request) {
        log.info(":>>> 开始获取分页活动信息:{}", JSON.toJSONString(request));
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());

        Query query = new Query();
        //是否获取已经参与的活动
        List<UserActivityTaskRanking> rankings = userActivityTaskRankingService.findByUserId(request.getUserId());
        if (CollectionUtils.isEmpty(rankings)) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
        List<String> ids = rankings.stream().map(ranking -> ranking.getActivityId()).collect(Collectors.toList());
        query.addCriteria(Criteria.where("id").in(ids));
        // 过滤打卡类的活动
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, ActivityInfo.class);
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
        Sort sort = Sort.by(Sort.Direction.DESC, "startTime");
        query.with(sort);
        query.with(pageRequest);
        List<ActivityInfo> infoList = mongoTemplate.find(query, ActivityInfo.class);

        long now = System.currentTimeMillis();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        List<ActivityInfoVo> activityInfoVos = new ArrayList<>();
        for (ActivityInfo activityInfo : infoList) {
            ActivityInfoVo activityInfoVo = new ActivityInfoVo();
            activityInfoVo.setId(activityInfo.getId());
            activityInfoVo.setImageUrl(activityInfo.getImageUrl());
            activityInfoVo.setH5Url(String.format(activityInfoUrl, activityInfo.getId(), request.getMinitoken()));
            activityInfoVo.setName(activityInfo.getName());
            activityInfoVo.setDescription(activityInfo.getName());
            String start = sdf.format(activityInfo.getStartTime());
            String end = sdf.format(activityInfo.getEndTime());
            activityInfoVo.setTimeRange(start + "~" + end);

            int status = 2;
            String statusDesc = "已结束";
            if (activityInfo.getStartTime().getTime() <= now && activityInfo.getEndTime().getTime() > now) {
                status = 1;
                statusDesc = "报名中";
            }
            activityInfoVo.setStatus(status);
            activityInfoVo.setStatusDesc(statusDesc);
            Query query1 = new Query().addCriteria(Criteria.where("activityId").is(activityInfo.getId()));
            Long joinedTotal = userActivityTaskRankingService.count(query1);
            activityInfoVo.setJoinedTotal(joinedTotal + activityInfo.getInitJoinNum());
            activityInfoVos.add(activityInfoVo);
        }
        return PageableExecutionUtils.getPage(activityInfoVos, pageRequest, () -> count);
    }

    @Override
    public List<PlatformActivityInfo> getPublicActivityInfo(String platform, String appId) {
        if (StringUtils.isBlank(appId)) {
            appId = "1112166368";
        }
        Query query = new Query().addCriteria(Criteria.where("platform").is(platform).and("appId").is(appId).and("status").is(true));
        List<ActivityPlatformConfig> apcList = mongoTemplate.find(query, ActivityPlatformConfig.class);
        List<String> idList = apcList.stream().map(apc -> apc.getActivityId()).collect(Collectors.toList());
        query = new Query().addCriteria(Criteria.where("id").in(idList));
        query.with(Sort.by(Sort.Order.asc("startTime")));
        return mongoTemplate.find(query, PlatformActivityInfo.class);
    }

    @Override
    public Page<ActivityInfo> activityList(ActivityVO request) {
        log.info(":>>> 开始获取活动信息:{}", JSON.toJSONString(request));
        if (Objects.isNull(request)) {
            request = new ActivityVO();
        }
        List<String> activityPublishedIds = new ArrayList<>();
        if (StringUtils.isNotBlank(request.getPlatform())) {
            List<ActivityPlatformConfig> configs = activityPlatformConfigService.find(request.getPlatform());
            if (!Objects.isNull(configs) && !CollectionUtils.isEmpty(configs)) {
                for (ActivityPlatformConfig config : configs) {
                    if (StringUtils.isNotBlank(config.getActivityId()) && !activityPublishedIds.contains(config.getActivityId())) {
                        activityPublishedIds.add(config.getActivityId());
                    }
                }
            }
        }
        log.info(":>>> 平台:{} 发布的活动活动:{}", request.getPlatform(), JSON.toJSON(activityPublishedIds));
        Query query1 = new Query();
        if (!CollectionUtils.isEmpty(activityPublishedIds)) {
            query1.addCriteria(Criteria.where("id").in(activityPublishedIds));
        }
        // 过滤打卡类的活动
        query1.addCriteria(Criteria.where("taskType").ne(4));
        query1.addCriteria(Criteria.where("deleted").ne(true));
        // 已经发布的活动
//        query1.addCriteria(Criteria.where("published").is(Boolean.TRUE));
        long count = mongoTemplate.count(query1, ActivityInfo.class);
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query1.with(sort);
        List<ActivityInfo> infos1 = mongoTemplate.find(query1.with(pageRequest), ActivityInfo.class);
        return PageableExecutionUtils.getPage(infos1, pageRequest, () -> count);
    }

    @Override
    public UserParticipateActivityInfo anonymousQuery(UserPO userPO, String activityId) {
        log.info(":>>> 匿名查看活动详情:用户:{},{}", activityId, userPO);
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 参数错误:活动ID为空", activityId);
            throw new BusinessException("活动ID为空");
        }
        if (StringUtils.isNotBlank(activityId) && Objects.nonNull(userPO) && StringUtils.isNotBlank(userPO.getId())) {
            log.info(":>>> 用户已经登陆:{}", userPO);
            return this.query(userPO, activityId, Boolean.TRUE, "");
        }
        UserParticipateActivityInfo userParticipateActivityInfo = new UserParticipateActivityInfo();
        ActivityInfo activityInfo = this.findOne(activityId);
        userParticipateActivityInfo.setActivityInfo(activityInfo);
        userParticipateActivityInfo.setOpenMiniJumpLink(activityInfo.getOpenMiniJumpLink());
        userParticipateActivityInfo.setMiniJumpLinkTextDesc(activityInfo.getMiniJumpLinkTextDesc());
        userParticipateActivityInfo.setMiniJumpLink(activityInfo.getMiniJumpLink());
        userParticipateActivityInfo.setJoined(false);//匿名查询活动详情为false
        return userParticipateActivityInfo;
    }

    /**
     * @param userPO
     * @param id
     * @param no
     * @return
     */
    @Override
    public UserParticipateActivityInfo query(UserPO userPO, String id, Boolean no, String platform) {
        log.info(":>>> 开始获取活动详情:{},{}", JSON.toJSONString(userPO), id);
        Long start = System.currentTimeMillis();
        if (StringUtils.isBlank(id) || Objects.isNull(userPO)) {
            log.error(":>>> 活动或用户ID为空");
            throw new BusinessException("活动或用户ID为空");
        }

        // 1:活动，2：收款
//        activityDauDataService.incr(userPO.getId(), id, 1);
        HashMap<String, ActivityTaskInfo> tashCach = new HashMap();
        Date date = new Date();
        final String userId = userPO.getId();
        List<String> uids = visitorUserService.findCorrentUserId(userId);
        if (!uids.contains(userId)) {
            uids.add(userId);
        }
//        List<String> uids = Arrays.asList(userId);
        log.info(":>>> 用户:{} 相关联的账户:{},耗时:{} 毫秒", userId, uids.size(), System.currentTimeMillis() - date.getTime());
        ActivityRewardRule activityRewardRule = new ActivityRewardRule();
        ActivityInfo activityInfo = this.findOne(id);
        UserParticipateActivityInfo userParticipateActivityInfo = userUpInfoService.findBy(id, userId, uids);
        if (Objects.isNull(userParticipateActivityInfo)) {
            userParticipateActivityInfo = new UserParticipateActivityInfo();
            // 未报名
            userParticipateActivityInfo.setJoined(false);
            // 未开始
            userParticipateActivityInfo.setCurrentStep(0);
            // 未开始
            userParticipateActivityInfo.setStatus("1");
            activityInfo.setJoined(false);
        } else {
//            userParticipateActivityInfo.setJoined(true);
            userParticipateActivityInfo.setSignUpTime(userParticipateActivityInfo.getSignUpTime());
            activityInfo.setJoined(userParticipateActivityInfo.getJoined());
        }
        // 设置活动信息
        activityInfo.setReTryQaNum(userParticipateActivityInfo.getReTryQaNum());
        userParticipateActivityInfo.setActivityInfo(activityInfo);
        userParticipateActivityInfo.setOpenMiniJumpLink(activityInfo.getOpenMiniJumpLink());
        userParticipateActivityInfo.setMiniJumpLinkTextDesc(activityInfo.getMiniJumpLinkTextDesc());
        userParticipateActivityInfo.setMiniJumpLink(activityInfo.getMiniJumpLink());
        if (Boolean.FALSE.equals(userParticipateActivityInfo.getJoined())) {
            log.error(":>>> 用户:{} 未参加活动:{},使用手机号查询是否参与活动", userId, id);
        }
        if ("before".equals(activityInfo.getType()) && activityInfo.getVolunteerTimeDigitalCa()) {
            userPO.setMobile(userParticipateActivityInfo.getMobile());
            userPO.setId(userParticipateActivityInfo.getUserId());
            userPO.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userPO.setUniversityName(userParticipateActivityInfo.getUniversityName());
            userPO.setOpenId(userParticipateActivityInfo.getOpenId());
            userPO.setUnionId(userParticipateActivityInfo.getUnionId());
            userPO.setAppId(userParticipateActivityInfo.getAppId());
            userPO.setName(userParticipateActivityInfo.getName());
            this.platformOtherActivityService.updateUserInfo(userPO, activityInfo.getId());
        }
        // 电子证书
        Date afterQueryP = new Date();
        log.info(":>>> 查询活动报名:{},{} 耗时:{} 毫秒!", activityInfo.getId(), userId, afterQueryP.getTime() - date.getTime());
        List<ActivityTaskInfo> taskInfos = this.getActivityTaskInfo(id);
        for (ActivityTaskInfo activityTaskInfo : taskInfos) {
            this.setActivityTaskDetail(activityInfo, activityTaskInfo, userId);
            userParticipateActivityInfo.getTaskInfos().put(activityTaskInfo.getTaskBizType().name(), activityTaskInfo);
            tashCach.put(activityTaskInfo.getTaskBizType().name(), activityTaskInfo);
        }
        userParticipateActivityInfo.setTasks(taskInfos);
        Date startOffLine = new Date();
        // 线下志愿活动
        if (Boolean.TRUE.equals(activityInfo.getHasOffLine())) {
            log.info(":>>> 活动有线下活动:{}", activityInfo.getId());
            ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityInfo.getId(), TaskBizType.OFF_LINE.name());
            log.info(":>>> 活动有线下活动:{},状态:{},{} ", activityInfo.getId(), userId, JSON.toJSONString(printDomain));
            /**
             * 线下组织活动状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
             */
            ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.OFF_LINE.name());
            if (Objects.isNull(taskRule)) {
                log.error(":>>> 活动:{} 没有没有配置:{} 任务明细", activityInfo.getId(), TaskBizType.OFF_LINE.name());
                throw new BusinessException("活动没有配置线下任务规则明细");
            }
            log.info(":>>> 活动:{} 线下活动任务是否需要审核:{}", activityInfo.getId(), activityInfo.getOffLineNeedVerify());
            if (Boolean.TRUE.equals(activityInfo.getOffLineNeedVerify())) {
                if (printDomain.getTotalNum().intValue() == 0) {
                    userParticipateActivityInfo.setOffLineStatus(0);
                    activityRewardRule.setOffLineStatus(false);
                } else {
                    if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                        userParticipateActivityInfo.setOffLineStatus(4);
                        activityRewardRule.setOffLineStatus(true);
                    } else {
                        userParticipateActivityInfo.setOffLineStatus(3);
                        activityRewardRule.setOffLineStatus(false);
                    }
                }
            } else {
                if (printDomain.getTotalNum().intValue() > 0) {
                    userParticipateActivityInfo.setOffLineStatus(3);
                    activityRewardRule.setOffLineStatus(true);
                } else {
                    userParticipateActivityInfo.setOffLineStatus(0);
                    activityRewardRule.setOffLineStatus(false);
                }
            }

        }
        Date startWelfare = new Date();
        log.info(":>>> 查询活动报名--> 结束线下志愿:{},{} 耗时:{} 毫秒!", activityInfo.getId(), userId, startWelfare.getTime() - startOffLine.getTime());
        // 线下志愿福利
        if (Boolean.TRUE.equals(activityInfo.getHasVolunteerWelfare())) {
            log.info(":>>> 活动有志愿福利:{}", activityInfo.getId());
            ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityInfo.getId(), TaskBizType.WELFARE.name());
            log.info(":>>> 活动志愿福利:{},状态:{},{} ", activityInfo.getId(), userId, JSON.toJSONString(printDomain));
            /**
             * 线下组织活动状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
             */
            ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.WELFARE.name());
            if (Objects.isNull(taskRule)) {
                log.error(":>>> 活动:{} 没有配置:{} 任务明细", activityInfo.getId(), TaskBizType.WELFARE.name());
                throw new BusinessException("活动没有配置志愿福利规则明细");
            }
            if (printDomain.getTotalNum().intValue() == 0) {
                userParticipateActivityInfo.setVolunteerWelfareStatus(0);
                activityRewardRule.setVolunteerWelfareStatus(false);
            } else {
                if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                    userParticipateActivityInfo.setVolunteerWelfareStatus(4);
                    activityRewardRule.setVolunteerWelfareStatus(true);
                } else {
                    userParticipateActivityInfo.setVolunteerWelfareStatus(3);
                    activityRewardRule.setVolunteerWelfareStatus(false);
                }
            }
        }
        Date startBroadcast = new Date();
        log.info(":>>> 查询活动报名--> 开始直播:{},{} 耗时:{} 毫秒!", activityInfo.getId(), userId, startBroadcast.getTime() - startWelfare.getTime());
        // 直播任务
        if (Boolean.TRUE.equals(activityInfo.getHasBroadcast())) {
            log.info(":>>> 活动有直播任务:{}", activityInfo.getId());
            ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityInfo.getId(), TaskBizType.BROADCASAT.name());
            log.info(":>>> 活动直播任务:{},状态:{},{} ", activityInfo.getId(), userId, JSON.toJSONString(printDomain));
            /**
             * 直播任务状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
             */
            ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.BROADCASAT.name());
            if (Objects.isNull(taskRule)) {
                log.error(":>>> 活动:{} 没有配置:{} 任务明细", activityInfo.getId(), TaskBizType.BROADCASAT.name());
                throw new BusinessException("活动没有配置志愿福利规则明细");
            }
            if (printDomain.getTotalNum().intValue() == 0) {
                userParticipateActivityInfo.setBroadcastStatus(0);
                activityRewardRule.setBroadcastStatus(false);
            } else {
                if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                    userParticipateActivityInfo.setBroadcastStatus(4);
                    activityRewardRule.setBroadcastStatus(true);
                } else {
                    userParticipateActivityInfo.setBroadcastStatus(3);
                    activityRewardRule.setBroadcastStatus(false);
                }
            }
        }
        // 承办单位
        if (Boolean.TRUE.equals(activityInfo.getHasOrganizer())) {
            ActivityTaskInfo taskInfo = tashCach.get(TaskBizType.ORGANIZER.name());
            if (Objects.isNull(taskInfo)) {
                log.error(":>>> 活动:{} 没有配置申办单位任务:请联系管理员", activityInfo.getId());
                throw new BusinessException("活动没有配置申办单位任务:请联系管理员");
            }
            List<String> orgIds = new ArrayList<>();
            ActivityOrganizerInfo activityOrganizerInfo = null;
            if (!CollectionUtils.isEmpty(uids)) {
                Query query = new Query().addCriteria(Criteria.where("ownerUserId").in(uids).and("activityId").is(activityInfo.getId()));
                List<ActivityOrganizerInfo> orgs = mongoTemplate.find(query, ActivityOrganizerInfo.class);
                log.info(":>>> 用户:{},活动:{} 关联的承办单位个数:{}", JSON.toJSONString(uids), id, orgs == null ? 0 : orgs.size());
                if (Objects.isNull(orgs) || CollectionUtils.isEmpty(orgs)) {
                    //可能会出现不一致，情况。后续会再改
                    activityOrganizerInfo = new ActivityOrganizerInfo();
                    activityOrganizerInfo.setName(userParticipateActivityInfo.getName());
                    activityOrganizerInfo.setMobile(userParticipateActivityInfo.getMobile());
                    activityOrganizerInfo.setUniversityId(userParticipateActivityInfo.getUniversityId());
                    activityOrganizerInfo.setUniversityName(userParticipateActivityInfo.getUniversityName());
                    activityOrganizerInfo.setQq(userParticipateActivityInfo.getQq());
                } else {
                    for (ActivityOrganizerInfo o : orgs) {
                        orgIds.add(o.getId());
                        if (Objects.nonNull(o.getStatus()) && o.getStatus().compareTo(1) == 0) {
                            activityOrganizerInfo = o;
                        }
                    }
                    if (Objects.isNull(activityOrganizerInfo)) {
                        activityOrganizerInfo = orgs.get(0);
                    }
                }
            }

            ActivityRewardRule orgActivityRewardRule = new ActivityRewardRule();
            orgActivityRewardRule.setQaStatus(true);
            orgActivityRewardRule.setOffLineStatus(true);
            Double q = 0.0D;
            if (!CollectionUtils.isEmpty(orgIds)) {
                q = getOrgQByOrgIds(id, taskInfo.getId(), orgIds);
            }
            if (Objects.nonNull(q)) {
                BigDecimal b = new BigDecimal(q);
                q = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            // 工作量
            orgActivityRewardRule.setToMatchValue(q == null ? 1 : q + 1);
            orgActivityRewardRule.setActivityId(id);
            orgActivityRewardRule.setTaskId(taskInfo.getId());

            ActivityRewardRule rule = activityRewardRuleService.match(id, taskInfo.getId(), Boolean.FALSE, Boolean.FALSE, orgActivityRewardRule);
            log.info(":>>> 获取申办单位的任务进度:{}", taskInfo.getId());
            if (Objects.nonNull(rule)) {
                rule.setPlatform(platform);
            }
            ActivityTaskDataDomain d = this.getTaskDataDomain(taskInfo, userId, rule, uids);
            if (Objects.isNull(activityOrganizerInfo)) {
                // 未报名
                userParticipateActivityInfo.setOrganizerStatus(3);
            } else {
                if (StringUtils.isBlank(activityOrganizerInfo.getId())) {
                    userParticipateActivityInfo.setOrganizerStatus(3);
                    d.setOrgName(" ");
                } else {
                    if (activityOrganizerInfo.getStatus().compareTo(1) == 0) {
                    }
                    userParticipateActivityInfo.setOrganizerStatus(activityOrganizerInfo.getStatus());
                    d.setOrgName(activityOrganizerInfo.getOrgName());
                }
                d.setUniversityName(activityOrganizerInfo.getUniversityName());
            }
            // 设置承办单位任务量
            if (Objects.nonNull(taskInfo)) {
                d.setBizId(taskInfo.getId());
                d.setBizType(taskInfo.getTaskBizType());
                d.setTips(taskInfo.getH5Tips());
                d.setHeaderTips(taskInfo.getHeaderTips());
                d.setInviteButtonTips(taskInfo.getInviteButtonTips());
                d.setInviteBackGroundImageUrl(taskInfo.getInviteBackGroundImageUrl());
                d.setShareInviteButtonType(taskInfo.getShareInviteButtonType());
                d.setShareInviteButtonBackGroundImgUrl(taskInfo.getShareInviteButtonBackGroundImgUrl());
                if (StringUtils.isNotBlank(taskInfo.getTaskAlias())) {
                    d.setTaskAlias(taskInfo.getTaskAlias());
                }
                d.setTaskPassAuditImgUrl(taskInfo.getTaskPassAuditImgUrl());
                d.setTaskPendAuditImgUrl(taskInfo.getTaskPendAuditImgUrl());
            }
            userParticipateActivityInfo.getDatas().put("ORGANIZER", d);
        }
        // 邀请任务
        ActivityTaskInfo taskInfo = tashCach.get(TaskBizType.INVITE.name());
        Double q = 0.0D;
        if ("qq".equals(platform) && Boolean.TRUE.equals(activityInfo.getHasPoint())) {
            Long c = userInviteRecordService.getInviteUserCount(userId, activityInfo.getId(), taskInfo.getId(), true);
            log.info(":>>> 平台是:{},用户:{},活动:{} 邀请人数:{}", platform, userId, activityInfo.getId(), c);
            q = Double.valueOf(c + "");
        } else if ("h5++".equals(activityInfo.getType()) || "contest-plus".equals(activityInfo.getType()) || ("qq" + "-mini" + "-plus-noncontest").equals(activityInfo.getType())) {
            UserActivityPointRanking ranking = userActivityPointRankingService.find(userId, "", id);
            if (Objects.nonNull(ranking)) {
                q = ranking.getQuantity();
                log.info(":>>> 用户:{} 活动:{} 积分排行榜积分:{}", userId, id, q);
            }
        } else {
            q = this.getTaskQuantityByUids(activityInfo.getId(), taskInfo.getId(), uids);
        }
        if (Objects.nonNull(q)) {
            BigDecimal b = new BigDecimal(q);
            q = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();

        }
        activityRewardRule.setToMatchValue(q);
        userParticipateActivityInfo.setTotalValue(q);
        if (Boolean.TRUE.equals(activityInfo.getHasQa())) {
            if (Objects.isNull(userParticipateActivityInfo.getPassed())) {
                activityRewardRule.setQaStatus(Boolean.FALSE);
            } else {
                activityRewardRule.setQaStatus(userParticipateActivityInfo.getPassed());
                ///
            }
        }
        activityRewardRule.setActivityId(id);
        activityRewardRule.setTaskId(taskInfo.getId());
        ActivityRewardRule rule = activityRewardRuleService.match(id, taskInfo.getId(), activityInfo.getHasQa() && activityInfo.getCaRules().contains(TaskBizType.QA), activityInfo.getHasOffLine() && activityInfo.getCaRules().contains(TaskBizType.OFF_LINE), activityRewardRule);
        if (Objects.nonNull(rule)) {
            rule.setToMatchValue(q);
            rule.setPlatform(platform);
        }
        ActivityTaskDataDomain d = this.getTaskDataDomain(taskInfo, userId, rule, uids);
        if (Objects.nonNull(d)) {
            d.setHeaderTips(taskInfo.getHeaderTips());
            d.setQ(q);
        }
        if (Boolean.TRUE.equals(activityInfo.getDoQaHasCa())) {

            log.info(":>>> 活动配置了答题可获得证书:{}", activityInfo.getId());
            if (Boolean.TRUE.equals(activityInfo.getHasMultiQa())) {
                UserQaInfo userQaInfo = this.getUserQa(userId, activityInfo.getId());
                if (Objects.isNull(userQaInfo)) {
                    d.setContestCaName("暂无证书");
                } else {
                    d.setContestCaName(userQaInfo.getCaName());
                }
//                d.setContestCaName(userParticipateActivityInfo.getContestCaName());
            } else {
                String contestCaName = activityQaRuleService.getQaCa(activityInfo.getId(), null, userParticipateActivityInfo.getQaScore().intValue());
                d.setContestCaName(contestCaName);
            }
            if (StringUtils.isBlank(d.getContestCaName())) {
                d.setContestCaName("暂无证书");
            }
        }
        log.info(":>>> 活动:{},答题是否可获得证书:{},是否有多级答题:{},答题获得的证书:{}", activityInfo.getId(), activityInfo.getDoQaHasCa(), activityInfo.getHasMultiQa(), d.getContestCaName());
        // 设置承办单位任务量
        if (Objects.nonNull(taskInfo)) {
            d.setBizId(taskInfo.getId());
            d.setBizType(taskInfo.getTaskBizType());
            d.setTips(taskInfo.getH5Tips());
            d.setHeaderTips(taskInfo.getHeaderTips());
            d.setHeaderSubTips(taskInfo.getHeaderSubTips());
            d.setLayoutNo(taskInfo.getLayoutNo());
            d.setInviteButtonTips(taskInfo.getInviteButtonTips());
            d.setInviteBackGroundImageUrl(taskInfo.getInviteBackGroundImageUrl());
            d.setShareInviteButtonType(taskInfo.getShareInviteButtonType());
            d.setShareInviteButtonBackGroundImgUrl(taskInfo.getShareInviteButtonBackGroundImgUrl());
            d.setCertificateFirstLevel(activityInfo.getCertificateFirstLevel());
            d.setBackGroundImageUrl(taskInfo.getBackGroundImageUrl());
        }
        log.info(":>>> 获取的贡献值提示语是:{}", JSON.toJSON(d));
        userParticipateActivityInfo.getDatas().put("INVITE", d);

        if (Objects.isNull(rule)) {
            userParticipateActivityInfo.setCaName("暂无证书");
        } else {
            userParticipateActivityInfo.setCaName(rule.getCaName());
            userParticipateActivityInfo.setVolunteerDuration(rule.getVolunteerDuration());
        }
        userParticipateActivityInfo.setAvatarUrl(userPO.getAvatarUrl());
        if (Objects.isNull(userParticipateActivityInfo.getQaScore())) {
            userParticipateActivityInfo.setQaScore(0D);
        }
        log.info(":>>> 活动任务是否显现电子证书:{},{}", activityInfo.getName(), taskInfo.getShowDigit());

        if (Boolean.TRUE.equals(taskInfo.getShowDigit())) {
            userParticipateActivityInfo.getActivityInfo().setDigitalCaDetail(taskInfo.getDigitCaDetail());
            userParticipateActivityInfo.getActivityInfo().setDigitCaDetail(taskInfo.getDigitCaDetail());
            userParticipateActivityInfo.getActivityInfo().setShowDigit(Boolean.TRUE);
        } else {
            userParticipateActivityInfo.getActivityInfo().setDigitalCaDetail(taskInfo.getDigitCaDetail());
            userParticipateActivityInfo.getActivityInfo().setDigitCaDetail(taskInfo.getDigitCaDetail());
            userParticipateActivityInfo.getActivityInfo().setShowDigit(Boolean.FALSE);
        }
        if (Boolean.TRUE.equals(no)) {
            // 匿名登陆
            log.info(":>>> 用户你匿名登陆");
            if (Objects.nonNull(userParticipateActivityInfo.getActivityInfo())) {
                userParticipateActivityInfo.getActivityInfo().setAfterSignUpDetail(userParticipateActivityInfo.getActivityInfo().getBeforeSignUpDetail());
            }
        }
        log.info(":>>> 用户:{},活动得分:{},{}", userId, id, userParticipateActivityInfo.getQaScore());
        if (Objects.nonNull(activityInfo.getRecieveRewardStartTime()) && Objects.nonNull(activityInfo.getRecieveRewardEndTime())) {
            if (date.after(activityInfo.getRecieveRewardStartTime()) && date.before(activityInfo.getRecieveRewardEndTime())) {
                userParticipateActivityInfo.setCaRecieveCa(true);
            } else {
                userParticipateActivityInfo.setCaRecieveCa(false);
            }
        } else {
            userParticipateActivityInfo.setCaRecieveCa(false);
        }
//        log.info(":>>> 活动的查询结果:{}", JSON.toJSONString(userParticipateActivityInfo));
        if (StringUtils.isNotBlank(userParticipateActivityInfo.getMobile()) && Objects.nonNull(userParticipateActivityInfo.getQaScore())) {
            if (Boolean.FALSE.equals(userParticipateActivityInfo.getJoined())) {
                userParticipateActivityInfo.setJoined(Boolean.TRUE);
            }
        }
        if (userParticipateActivityInfo.getCaRecieveCa()) {
            PayConfigPage payConfigPage = activityPayConfigService.findByActivityId(activityInfo.getId(), 0);
            userParticipateActivityInfo.setWechatPayUrl(platformConfigService.getBizFrontPayDomain() + platformConfigService.getPayCatalogue() + String.format(ActivityPayConfigService.activityPayUrl, activityInfo.getId(), activityInfo.getThemeColor(), payConfigPage.getAppId()));
        }
        log.info(":>>> 结束查询用户:{} 活动:{} 进度耗时:{} 毫秒", userId, id, System.currentTimeMillis() - start);
        return userParticipateActivityInfo;
    }

    @Override
    public ActivityInfo findOne(String id) {
        log.info(":>>> 开始查询活动信息:{}", id);
        Long start = System.currentTimeMillis();
        if (StringUtils.isBlank(id)) {
            log.error(":>>> 活动ID为空");
            return null;
//            throw new BusinessException("活动ID为空");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        ActivityInfo activityInfo = mongoTemplate.findOne(query, ActivityInfo.class);
//        if (Objects.isNull(activityInfo)) {
//            log.error(":>>> 活动不存在:{}", id);
//            throw new BusinessException("活动不存在");
//        }
        log.info(":>>> 结束查询活动信息耗时:{},{} 毫秒", id, System.currentTimeMillis() - start);
        return activityInfo;
    }

    @Override
    public RankingListResVO getUniversityContestRanking(RankingListQueryVO req, UserPO userPO) {
        log.info(":>>> 开始获取高校排行榜:{}", JSON.toJSONString(req));
        Long currentTime = System.currentTimeMillis();
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getTime())) {
            log.error(":>>> 获取活动竞赛排行榜参数错误:活动ID、时间纬度为空");
            throw new BusinessException("获取活动竞赛排行榜参数错误:活动ID、时间纬度为空");
        }
        ActivityInfo activityInfo = cacheActivityService.findById(req.getActivityId());
        ActivityTaskInfo activityTaskInfo = this.getActivityTaskInfo(req.getActivityId(), req.getTaskBizType());
        if (Objects.isNull(activityTaskInfo)) {
            log.error(":>>> 活动:{} 无可用的任务,请联系客服", req.getActivityId());
            throw new BusinessException("活动无可用的任务,请联系客服");
        }
        req.setTaskId(activityTaskInfo.getId());
        req.setPageSize(10);
        String universityId = visitorUserService.userUniversityId(userPO.getId(), req.getActivityId());
        log.info(":>>> 用户:{} 活动:{} 所在大学ID:{}", userPO.getId(), req.getActivityId(), universityId);
        UniversityInfo universityInfoMy = universityService.get(universityId);
//        req.setPage(1);
        switch (req.getTime()) {
            // 所有
            case "all": {
                log.info(":>>> 开始获取高校竞赛排行榜全部数据:{}", req.getTime());
                Query query = new Query();
                query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
//                query.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskId").is
//                (activityTaskInfo.getId()));
//                query.with(new Sort(Sort.Direction.DESC, "quantity"));
                Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
                query.with(sort);
                query.limit(req.getPageSize());
                Long count = this.getUniversityContestRankingCount(req.getActivityId(), req.getTaskId());
                if (count.intValue() > activityTaskInfo.getRangNum()) {
                    count = Long.valueOf(activityTaskInfo.getRangNum() + "");
                    log.info(":>>> 活动:{} 任务:{} 排行榜数量大于任务配置上限:{}", req.getActivityId(), req.getTaskId(), count);
                }
                Integer totalPages = 0;
                if (count.intValue() == 0) {
                    totalPages = 0;
                } else {
                    if (count.intValue() % req.getPageSize() == 0) {
                        totalPages = count.intValue() / req.getPageSize();
                    } else {
                        totalPages = count.intValue() / req.getPageSize() + 1;
                    }
                }
                PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
                List<UniversityActivityTaskRanking> rankings = new ArrayList<>();
                if (totalPages < req.getPage()) {
                    rankings = new ArrayList<>();
                    log.info(":>>> 排行榜总页数:{} 是最后一页:{}", totalPages, req.getPage());

                } else {
//                    rankings =
//                            rankService.getUniversityRankListCache(req.getActivityId(), req.getPage());
                    if (Objects.isNull(rankings) || CollectionUtils.isEmpty(rankings)) {
                        rankings = mongoTemplate.find(query.with(pageRequest), UniversityActivityTaskRanking.class);
                        if (Objects.isNull(rankings)) {
                            rankings = new ArrayList<>();
                        }
                        rankService.setUniversityRankListCache(req.getActivityId(), req.getPage(), rankings);
                    }

                }
                if (CollectionUtils.isEmpty(rankings)) {
                    rankings = new ArrayList<>();
                }
                List<String> unames = new ArrayList<>();
                for (UniversityActivityTaskRanking d : rankings) {
                    if (StringUtils.isNotBlank(d.getName())) {
                        unames.add(d.getName().trim());
                    }
                }
                Query queryUni = new Query();
                queryUni.addCriteria(Criteria.where("name").in(unames));
                queryUni.addCriteria(Criteria.where("deleted").ne(true));
                queryUni.addCriteria(Criteria.where("dataType").ne(3));
                List<UniversityInfo> universityInfos = mongoTemplate.find(queryUni, UniversityInfo.class);
                HashMap<String, UniversityInfo> universityInfoHashMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(universityInfos)) {
                    for (UniversityInfo universityInfo : universityInfos) {
                        universityInfoHashMap.put(universityInfo.getName(), universityInfo);
                    }
                }
                RankingListResVO rankingListResVO = new RankingListResVO();
                List<RankingList> rankingLists = new ArrayList<>();
                boolean in = false;
                int order = 1;
                int uOrder = 0;
                int orderNN = (req.getPage() - 1) * req.getPageSize() + 1;
                for (UniversityActivityTaskRanking d : rankings) {
                    String uName = StringUtils.isNotBlank(d.getName()) ? d.getName().trim() : "";
                    if (uName.equals(req.getUniversity())) {
                        in = true;
                        uOrder = order;
                    }
                    RankingList rankingList = new RankingList();
                    if (universityInfoHashMap.containsKey(uName)) {
                        rankingList.setImageUrl(universityInfoHashMap.get(uName).getLogo());
                    } else {
                        rankingList.setImageUrl(DEFAULT_UNIVERSITY_LOG);
                    }
                    rankingList.setName(uName);
                    if (Objects.nonNull(d.getQuantity())) {
                        BigDecimal b = new BigDecimal(d.getQuantity());
                        Double q = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                        rankingList.setQuantity(q);
                    }
                    rankingList.setRankUniversity();
                    rankingList.setOrderNo(orderNN);
                    rankingLists.add(rankingList);
                    order++;
                    orderNN++;
                }
                rankingListResVO.setDatas(rankingLists);
                rankingListResVO.setInRanking(in);
                rankingListResVO.setDetail(activityTaskInfo.getRankingListContent());
                String key = universityActivityRankingService.getUniversityRankKey(req.getActivityId());
                Long o = rankBaseService.getSingleRankOrder(key, universityId);
                Double q = rankBaseService.getSingleRankScore(key, universityId);
                if (Objects.isNull(q)) {
                    q = 0D;
                }
                if (Objects.isNull(o)) {
                    o = 0L;
                }
                rankingListResVO.setRankValue(q.intValue() + "人参与");
                rankingListResVO.setQuantity(q);
                rankingListResVO.setOrderNo(o.intValue());
                if (Objects.isNull(universityInfoMy)) {
                    this.setDefaultHead(rankingListResVO, "");
                } else {
                    rankingListResVO.setName(universityInfoMy.getName());
                    rankingListResVO.setImageUrl(universityInfoMy.getLogo());
                }
//                this.setRankName(rankingListResVO, req.getUserPO());
                rankingListResVO.setPage(req.getPage());
                rankingListResVO.setPageSize(req.getPageSize());
                rankingListResVO.setTotalPages(count.intValue() / req.getPageSize() + 1);
                log.info(":>>> 获取活动:{} 大学排行榜耗时:{} 毫秒", activityInfo.getName(), (System.currentTimeMillis() - currentTime));
                return rankingListResVO;
            }
            // 天
            case "day": {
                log.info(":>>> 开始获取高校竞赛排行榜天数据:{}", req.getTime());
                Query query = new Query();
                query.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskId").is(activityTaskInfo.getId()));
//                query.with(new Sort(Sort.Direction.DESC, "quantity"));
                Sort sortDay = Sort.by(Sort.Direction.DESC, "quantity");
                query.with(sortDay);
                query.limit(req.getPageSize());
                Long count = 50L;
//                Long count = mongoTemplate.count(query, UniversityActivityTaskRanking.class);
                PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
                List<UniversityActivityTaskRanking> rankings = rankService.getUniversityRankListCache(req.getActivityId(), req.getPage());
                if (Objects.isNull(rankings) || CollectionUtils.isEmpty(rankings)) {
                    rankings = mongoTemplate.find(query.with(pageRequest), UniversityActivityTaskRanking.class);
                    if (Objects.isNull(rankings)) {
                        rankings = new ArrayList<>();
                    }
                    rankService.setUniversityRankListCache(req.getActivityId(), req.getPage(), rankings);
                }
                if (CollectionUtils.isEmpty(rankings)) {
                    rankings = new ArrayList<>();
                }
                List<String> unames = new ArrayList<>();
                for (UniversityActivityTaskRanking d : rankings) {
                    if (StringUtils.isNotBlank(d.getName())) {
                        unames.add(d.getName().trim());
                    }
                }
                Query queryUni = new Query();
                queryUni.addCriteria(Criteria.where("name").in(unames));
                queryUni.addCriteria(Criteria.where("deleted").ne(true));
                queryUni.addCriteria(Criteria.where("dataType").ne(3));
                List<UniversityInfo> universityInfos = mongoTemplate.find(queryUni, UniversityInfo.class);
                HashMap<String, UniversityInfo> universityInfoHashMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(universityInfos)) {
                    for (UniversityInfo universityInfo : universityInfos) {
                        universityInfoHashMap.put(universityInfo.getName(), universityInfo);
                    }
                }
                RankingListResVO rankingListResVO = new RankingListResVO();
                List<RankingList> rankingLists = new ArrayList<>();
                boolean in = false;
                int order = 1;
                int uOrder = 1001;
                int orderNN = (req.getPage() - 1) * req.getPageSize() + 1;
                for (UniversityActivityTaskRanking d : rankings) {
                    String uName = StringUtils.isNotBlank(d.getName()) ? d.getName().trim() : "";
                    if (uName.equals(req.getUniversity())) {
                        in = true;
                        uOrder = order;
                    }
                    RankingList rankingList = new RankingList();

                    if (universityInfoHashMap.containsKey(uName)) {
                        rankingList.setImageUrl(universityInfoHashMap.get(uName).getLogo());
                    } else {
                        rankingList.setImageUrl(DEFAULT_UNIVERSITY_LOG);
                    }
                    rankingList.setName(uName);
                    rankingList.setQuantity(d.getQuantity());
                    rankingList.setRank(activityInfo.getRewardValueUnitDesc());
                    rankingList.setOrderNo(orderNN);
                    rankingLists.add(rankingList);
                    order++;
                    orderNN++;
                }
                rankingListResVO.setDatas(rankingLists);
                rankingListResVO.setInRanking(in);
                rankingListResVO.setDetail(activityTaskInfo.getRankingListContent());
                Query queryU = new Query();
                queryU.addCriteria(Criteria.where("name").is(req.getUniversity()).and("taskId").is(activityTaskInfo.getId()).and("activityId").is(req.getActivityId()));
//                queryU.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskId").is
//                (activityTaskInfo.getId()).and("name").is(req.getUniversity()));
                UniversityActivityTaskRanking day = mongoTemplate.findOne(queryU, UniversityActivityTaskRanking.class);
                if (Objects.isNull(day)) {
                    rankingListResVO.setOrderNo(0);
                    rankingListResVO.setQuantity(0.0D);
                } else {
                    rankingListResVO.setOrderNo(uOrder);
                    rankingListResVO.setQuantity(day.getQuantity());
                }
                rankingListResVO.setDetail(activityTaskInfo.getRankingListContent());
                if (Objects.isNull(req.getUserPO())) {
                    this.setDefaultHead(rankingListResVO, "");
                } else {
                    this.setDefaultHead(rankingListResVO, req.getUserPO().getAvatarUrl());
                }
                this.setRankName(rankingListResVO, req.getUserPO());
                rankingListResVO.setPage(req.getPage());
                rankingListResVO.setPageSize(req.getPageSize());
                rankingListResVO.setTotalPages(count.intValue() / req.getPageSize() + 1);
                return rankingListResVO;
            }
            default:
                break;
        }
        return null;
    }

    @Override
    public RankingListResVO getUniversityContestRanking2(RankingListQueryVO req, UserPO userPO) {
        log.info(":>>> 开始获取高校排行榜:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getTime())) {
            log.error(":>>> 获取活动竞赛排行榜参数错误:活动ID、时间纬度为空");
            throw new BusinessException("获取活动竞赛排行榜参数错误:活动ID、时间纬度为空");
        }
        //获取当前活动信息
        ActivityInfo activityInfo = cacheActivityService.findById(req.getActivityId());
        if (Objects.isNull(activityInfo)) {
            log.error(":>>> 活动:{} 活动不存在,请联系客服", req.getActivityId());
            throw new BusinessException("活动不存在,请联系客服");
        }
        //获取当前活动任务信息
        ActivityTaskInfo activityTaskInfo = this.getActivityTaskInfo(req.getActivityId(), req.getTaskBizType());
        if (Objects.isNull(activityTaskInfo)) {
            log.error(":>>> 活动:{} 无可用的任务,请联系客服", req.getActivityId());
            throw new BusinessException("活动无可用的任务,请联系客服");
        }
        req.setTaskId(activityTaskInfo.getId());
        RankingListResVO resultVo = null;
        if ("all".equals(req.getTime())) {
            resultVo = getRankingListResVOByAll(req, userPO, activityTaskInfo, activityInfo);
        }
        if ("day".equals(req.getTime())) {
            resultVo = getRankingListResVOByDay(req, activityTaskInfo, activityInfo);
        }
        return resultVo;
    }

    private RankingListResVO getRankingListResVOByDay(RankingListQueryVO req, ActivityTaskInfo activityTaskInfo, ActivityInfo activityInfo) {
        //封装返回值
        RankingListResVO resultVo = new RankingListResVO();
        resultVo.setDetail(activityTaskInfo.getRankingListContent());

        UserPO userPO = req.getUserPO();
        if (Objects.isNull(userPO)) {
            resultVo.setImageUrl(defaultHead);
        } else {
            resultVo.setImageUrl(userPO.getAvatarUrl());
            String name = StringUtils.isNotBlank(userPO.getNickName()) ? userPO.getNickName() : userPO.getName();
            resultVo.setName(name);
        }
        resultVo.setPage(req.getPage());
        resultVo.setPageSize(req.getPageSize());

        //查询 工作量
        Query queryU = new Query();
        Criteria criteria = Criteria.where("name").is(req.getUniversity()).and("taskId").is(activityTaskInfo.getId()).and("activityId").is(req.getActivityId());
        if (CollectionUtils.isNotEmpty(activityInfo.getExUniversity())) {
            criteria.and("universityId").nin(activityInfo.getExUniversity());
        }
        queryU.addCriteria(criteria);
        //过滤大学
        UniversityActivityTaskRanking day = mongoTemplate.findOne(queryU, UniversityActivityTaskRanking.class);
        if (Objects.nonNull(day)) {
            resultVo.setQuantity(day.getQuantity());
        }
        //查询 数据库 总数
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskId").is(activityTaskInfo.getId()));
        //过滤大学
        if (CollectionUtils.isNotEmpty(activityInfo.getExUniversity())) {
            query.addCriteria(Criteria.where("universityId").nin(activityInfo.getExUniversity()));
        }
        Long count = mongoTemplate.count(query, UniversityActivityTaskRanking.class);
        //设置总数
        resultVo.setTotal(count.intValue());
        if (count == 0) {
            return resultVo;
        }

        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        List<UniversityActivityTaskRanking> rankings = rankService.getUniversityRankListCache(req.getActivityId(), req.getPage());
        if (CollectionUtils.isEmpty(rankings)) {
            Sort sortDay = Sort.by(Sort.Direction.DESC, "quantity");
            query.with(sortDay);
            query.limit(req.getPageSize());
            query.with(pageRequest);
            rankings = mongoTemplate.find(query, UniversityActivityTaskRanking.class);
            if (Objects.isNull(rankings)) {
                return resultVo;
            }
            rankService.setUniversityRankListCache(req.getActivityId(), req.getPage(), rankings);
        }

        List<String> unames = rankings.stream().filter(d -> StringUtils.isNotBlank(d.getName())).map(UniversityActivityTaskRanking::getName).collect(Collectors.toList());

        //是否入榜,默认未入榜
        boolean inRanking = unames.contains(req.getUniversity());
        resultVo.setInRanking(inRanking);
        //获取logo信息
        HashMap<String, String> universityInfoHashMap = getUniversityLogoMap(unames);


        List<RankingList> rankingLists = new ArrayList<>();
        int order = 1;
        int uOrder = 1001;
        int orderNN = (req.getPage() - 1) * req.getPageSize() + 1;//序列号
        for (UniversityActivityTaskRanking d : rankings) {
            String uName = StringUtils.isNotBlank(d.getName()) ? d.getName().trim() : "";

            RankingList rankingList = new RankingList();

            rankingList.setImageUrl(DEFAULT_UNIVERSITY_LOG);
            if (universityInfoHashMap.containsKey(uName)) {
                rankingList.setImageUrl(universityInfoHashMap.get(uName));
            }
            rankingList.setName(uName);
            rankingList.setQuantity(d.getQuantity());
            rankingList.setRank(activityInfo.getRewardValueUnitDesc());
            rankingList.setOrderNo(orderNN);
            rankingLists.add(rankingList);
            if (uName.equals(req.getUniversity())) {
                uOrder = order;
            }
            order++;
            orderNN++;
        }
        resultVo.setDatas(rankingLists);
        resultVo.setOrderNo(uOrder);
        return resultVo;
    }

    /**
     * 获取 高校名称的 logo图标
     *
     * @param unames
     * @return
     */
    private HashMap<String, String> getUniversityLogoMap(List<String> unames) {
        //查询logo信息
        Query queryUni = new Query();
        queryUni.addCriteria(Criteria.where("name").in(unames));
        queryUni.addCriteria(Criteria.where("deleted").ne(true));
        queryUni.addCriteria(Criteria.where("dataType").ne(3));
        List<UniversityInfo> universityInfos = mongoTemplate.find(queryUni, UniversityInfo.class);
        HashMap<String, String> universityLogoHashMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(universityInfos)) {
            for (UniversityInfo universityInfo : universityInfos) {
                universityLogoHashMap.put(universityInfo.getName(), universityInfo.getLogo());
            }
        }
        return universityLogoHashMap;
    }

    private RankingListResVO getRankingListResVOByAll(RankingListQueryVO req, UserPO userPO, ActivityTaskInfo activityTaskInfo, ActivityInfo activityInfo) {

        //获取当前用户所在的大学信息
        String universityId = visitorUserService.userUniversityId(userPO.getId(), req.getActivityId());
        UniversityInfo universityInfoMy = universityService.get(universityId);
        log.info(":>>> 用户:{} 活动:{} 所在大学ID:{}", userPO.getId(), req.getActivityId(), universityId);

        //查询 数据库 总数
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        //过滤大学
        if (CollectionUtils.isNotEmpty(activityInfo.getExUniversity())) {
            query.addCriteria(Criteria.where("universityId").nin(activityInfo.getExUniversity()));
        }
        Long total = mongoTemplate.count(query, UniversityActivityTaskRanking.class);


        //创建返回值 结果集
        RankingListResVO resultVo = new RankingListResVO();
        //设置分页信息
        resultVo.setPage(req.getPage());
        resultVo.setPageSize(req.getPageSize());
        resultVo.setTotal(total.intValue());
        //设置当前 我的高校信息
        if (Objects.isNull(universityInfoMy)) {
            resultVo.setImageUrl(defaultHead);
        } else {
            resultVo.setName(universityInfoMy.getName());
            resultVo.setImageUrl(universityInfoMy.getLogo());
        }
        resultVo.setDetail(activityTaskInfo.getRankingListContent());

        String key = RedisKeyUtil.getUniversityRankPreKey(req.getActivityId());
        //获取子key的分数
        Double quantity = rankBaseService.getSingleRankScore(key, universityId);
        if (Objects.isNull(quantity)) {
            quantity = 0D;
        }
        resultVo.setQuantity(quantity);
        resultVo.setRankValue(quantity.intValue() + "人参与");

        //获取子key的名次
        Long orderNo = rankBaseService.getSingleRankOrder(key, universityId);
        if (Objects.isNull(orderNo)) {
            orderNo = 0L;
        }
        resultVo.setOrderNo(orderNo.intValue());

        if (resultVo.getTotalPages() < req.getPage()) {
            return resultVo;
        }
        //查询 高校活动任务排行 列表
        query.with(Sort.by(Sort.Direction.DESC, "quantity"));
        query.limit(req.getPageSize());
        query.with(PageRequest.of(req.getPage() - 1, req.getPageSize()));
        List<UniversityActivityTaskRanking> rankings = mongoTemplate.find(query, UniversityActivityTaskRanking.class);
        if (Objects.isNull(rankings)) {
            return resultVo;
        }
        rankService.setUniversityRankListCache(req.getActivityId(), req.getPage(), rankings);

        List<String> unames = rankings.stream().filter(d -> StringUtils.isNotBlank(d.getName())).map(UniversityActivityTaskRanking::getName).collect(Collectors.toList());

        //是否入排行榜
        resultVo.setInRanking(unames.contains(req.getUniversity()));

        //获取logo信息
        HashMap<String, String> universityLogoHashMap = getUniversityLogoMap(unames);

        int orderNN = (req.getPage() - 1) * req.getPageSize() + 1;//序列号

        List<RankingList> rankingLists = new ArrayList<>();
        for (UniversityActivityTaskRanking d : rankings) {
            RankingList rankingList = new RankingList();
            String uName = StringUtils.isNotBlank(d.getName()) ? d.getName().trim() : "";
            rankingList.setName(uName);
            rankingList.setImageUrl(DEFAULT_UNIVERSITY_LOG);
            if (universityLogoHashMap.containsKey(uName)) {
                rankingList.setImageUrl(universityLogoHashMap.get(uName));
            }
            if (Objects.nonNull(d.getQuantity())) {
                Double q = new BigDecimal(d.getQuantity()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                rankingList.setQuantity(q);
            }
            rankingList.setRankUniversity();
            rankingList.setOrderNo(orderNN);
            rankingLists.add(rankingList);
            orderNN++;
        }
        resultVo.setDatas(rankingLists);
        return resultVo;
    }

    @Override
    public RankingListResVO getOrganizerRanking(RankingListQueryVO req, UserPO userPO) {
        log.info(":>>> 开始获取申请机构排行:{},{}", JSON.toJSONString(req), JSON.toJSONString(userPO));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || Objects.isNull(req.getTaskBizType()) || StringUtils.isBlank(req.getTime())) {
            log.error(":>>> 获取活动申请机构排行榜参数错误:活动ID、时间纬度为空");
            throw new BusinessException("获取活动排行榜参数错误:活动ID、时间纬度为空");
        }
        ActivityTaskInfo taskInfo = activityTaskService.find(req.getActivityId(), req.getTaskBizType());
        if (Objects.isNull(taskInfo)) {
            log.error(":>>> 无配置的任务,请联系客服");
            throw new BusinessException("无配置的任务,请联系客服");
        }
        req.setTaskId(taskInfo.getId());
        String orgId = activityOrganizerInfoService.getOrganizerId("", userPO.getId());
        req.setOrganizerId(orgId);
        log.info(":>>> 任务信息:{},{}", taskInfo.getName(), taskInfo.getId());
        switch (req.getTime()) {
            // 周纬度
            // 累计
            case "all": {
                return this.getOrgAllRankList(req, taskInfo);
            }
            default:
                break;
        }
        return null;
    }

    @Override
    public RankingListResVO getUserTaskRanking(RankingListQueryVO req, UserPO userPO) {
        log.info(":>>> 获取用户活动任务排行榜:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getTime()) || Objects.isNull(req.getTaskBizType())) {
            log.error(":>>> 获取活动排行榜参数错误:活动ID、时间纬度为空");
            throw new BusinessException("获取活动排行榜参数错误:活动ID、时间纬度为空");
        }
        ActivityTaskInfo taskInfo = activityTaskService.find(req.getActivityId(), req.getTaskBizType());
        if (Objects.isNull(taskInfo)) {
            log.error(":>>> 无配置的任务,请联系客服");
            throw new BusinessException("无配置的任务,请联系客服");
        }
        req.setTaskId(taskInfo.getId());
        log.info(":>>> 任务信息:{},{}", taskInfo.getName(), taskInfo.getId());
        switch (req.getTime()) {
            // 周纬度
            case "week": {
                return this.getUserWeekRankList(req, userPO, taskInfo);
            }
            // 累计
            case "all": {
                return userRankListService.getUserAllRankList(req, userPO, taskInfo);
            }
            default:
                break;
        }
        return null;
    }

    @Override
    public Integer getUserTaskRankingOrderNo(RankingListQueryVO req) {
        log.info(":>>> 获取用户活动任务排行榜:{}", JSON.toJSONString(req));
        try {
            if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getTime()) || StringUtils.isBlank(req.getTaskId())) {
                log.error(":>>> 获取活动排行榜参数错误:活动ID、时间纬度为空");
                throw new BusinessException("获取活动排行榜参数错误:活动ID、时间纬度为空");
            }
            req.setTaskId(req.getTaskId());
            switch (req.getTime()) {
                // 周纬度
                case "week": {
                    Query query = new Query();
                    Criteria criteria1 = Criteria.where("activityId").is(req.getActivityId()).and("taskId").is(req.getTaskId());
                    query.addCriteria(criteria1);
//                    Aggregation customerAgg = Aggregation.newAggregation(
//                            Aggregation.project("userId","quantity"),
//                            Aggregation.match(criteria1),
//                            Aggregation.group("userId"),
//                            Aggregation.sort(new Sort(new Sort.Order(Sort.Direction.DESC, "quantity")))
//                    );
                    log.info(":>>> 活动ID:{},任务ID:{}", req.getActivityId(), req.getTaskId());
                    Date startWeekTime = TimeUtils.getBeginDayOfWeek();
                    Date endWeekTime = TimeUtils.getEndDayOfWeek();
                    Criteria criteria = new Criteria().andOperator(Criteria.where("weekTime").gte(TimeUtils.dateToISODate(startWeekTime)), Criteria.where("weekTime").lte(TimeUtils.dateToISODate(endWeekTime)));
                    query.addCriteria(criteria);
                    // 设置省查询
//                    this.setRankListProvince(query, req.getActivityId(), req.getProvince(), req.getUserPO());
//                    query.with(new Sort(Sort.Direction.DESC, "quantity"));
                    Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
                    query.with(sort);
                    query.limit(1000);
                    List<UserWeekActivityTaskRanking> rankings = mongoTemplate.find(query, UserWeekActivityTaskRanking.class);
                    if (CollectionUtils.isEmpty(rankings)) {
                        rankings = new ArrayList<>();
                    }
                    int userOrder = 1001;
                    int order = 1;
                    for (UserWeekActivityTaskRanking d : rankings) {
                        if (d.getUserId().equals(req.getUserId())) {
                            userOrder = order;
                        }
                        order++;
                    }
                    return userOrder;
                }
                // 累计
                case "all": {
                    List<UserActivityTaskRanking> rankings = userActivityTaskRankingService.findByActivityIdAndTaskId(req.getActivityId(), req.getTaskId());
                    if (CollectionUtils.isEmpty(rankings)) {
                        rankings = new ArrayList<>();
                    }
                    int order = 1;
                    int uOrder = 1001;
                    for (UserActivityTaskRanking d : rankings) {
                        if (req.getUserId().equals(d.getUserId())) {
                            uOrder = order;
                        }
                        order++;
                    }
                    return uOrder;
                }
                default:
                    break;
            }


        } catch (Exception e) {
            log.error(":>>> 获取排名错误:{}", e);
        }
        return null;
    }

    @Override
    public Page<UserInviteRecord> getUserInviteRecord(UserInviteQueryVO req) {
        log.info(":>>> 开始获取活动邀请信息:{}", JSON.toJSONString(req));
        if (Objects.isNull(req)) {
            req = new UserInviteQueryVO();
        }
        Query query = new Query();
        //List<String> uid = visitorUserService.findCorrentUserId(req.getUserId());
        List<String> uid = Arrays.asList(req.getUserId());
        if (!CollectionUtils.isEmpty(uid)) {
            query.addCriteria(Criteria.where("invitedByUserId").in(uid));
        } else {
            query.addCriteria(Criteria.where("invitedByUserId").is(req.getUserId()));
        }
        if (StringUtils.isNotBlank(req.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        }
        if (StringUtils.isNotBlank(req.getTaskId())) {
            query.addCriteria(Criteria.where("taskId").is(req.getTaskId()));
        }
        if (Objects.nonNull(req.getJoinStatus())) {
            query.addCriteria(Criteria.where("joinStatus").is(req.getJoinStatus()));
        }
        Long cu = System.currentTimeMillis();
//        query.withHint("{ 'invitedByUserId_-1_taskId_-1_joinStatus_1' : 1 }");
        Long count = mongoTemplate.count(query, mongoTemplate.getCollectionName(UserInviteRecord.class));
        log.info(":>>> ^_^ 结束获取邀请数量:{},邀请数量耗时:{} 毫秒", JSON.toJSONString(req), (System.currentTimeMillis() - cu));
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserInviteRecord> infos = mongoTemplate.find(query.with(pageRequest), UserInviteRecord.class);
        if (!CollectionUtils.isEmpty(infos)) {
            for (UserInviteRecord userInviteRecord : infos) {
                if (!StringUtils.isBlank(userInviteRecord.getInvitedToUserImageUrl()) && !StringUtils.isBlank(userInviteRecord.getInvitedToUserName())) {
                    continue;
                }
                String imageUrl = "";
                switch (req.getPlatform()) {
                    case "qq":
                        QQMiniUserPO userPO = qqMiniUserService.queryUserByAccountId(req.getAppId(), userInviteRecord.getInvitedToUserId());
                        if (Objects.nonNull(userPO.getAvatarUrl())) {
                            imageUrl = userPO.getAvatarUrl();
                        }
                        break;
                    case "wechat-h5":
                        Query queryH5 = new Query().addCriteria(Criteria.where("accountInfoId").is(userInviteRecord.getInvitedToUserId()));
//                        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
                        Sort sortH5 = Sort.by(Sort.Direction.DESC, "createdTime");
                        query.with(sortH5);
                        WechatH5UserPO wechatH5UserPO = mongoTemplate.findOne(queryH5, WechatH5UserPO.class);
                        if (Objects.nonNull(wechatH5UserPO) && StringUtils.isNotBlank(wechatH5UserPO.getAvatarUrl())) {
                            imageUrl = wechatH5UserPO.getAvatarUrl();
                        }
                        break;
                    case "wechat-mini":
                        Query queryMini = new Query().addCriteria(Criteria.where("accountInfoId").is(userInviteRecord.getInvitedToUserId()));
//                        queryMini.with(new Sort(Sort.Direction.DESC, "createdTime"));
                        Sort sortM = Sort.by(Sort.Direction.DESC, "createdTime");
                        queryMini.with(sortM);
                        WechatMiniUserPO wechatMiniUser = mongoTemplate.findOne(queryMini, WechatMiniUserPO.class);
                        if (Objects.nonNull(wechatMiniUser)) {
                            if (StringUtils.isNotBlank(wechatMiniUser.getAvatarUrl())) {
                                imageUrl = wechatMiniUser.getAvatarUrl();
                            }
                            if (StringUtils.isBlank(userInviteRecord.getInvitedToUserName())) {
                                userInviteRecord.setInvitedToUserName(wechatMiniUser.getNickName());
                            }
                        }
                        break;
                    case "douyin-mini":
                        Query queryDouyin = new Query().addCriteria(Criteria.where("accountInfoId").is(userInviteRecord.getInvitedToUserId()));
                        DouYinMiniUserPO douYinMiniUserPO = mongoTemplate.findOne(queryDouyin, DouYinMiniUserPO.class);
                        if (Objects.nonNull(douYinMiniUserPO)) {
                            if (StringUtils.isNotBlank(douYinMiniUserPO.getAvatarUrl())) {
                                imageUrl = douYinMiniUserPO.getAvatarUrl();
                            }
                            if (StringUtils.isBlank(userInviteRecord.getInvitedToUserName())) {
                                userInviteRecord.setInvitedToUserName(douYinMiniUserPO.getNickName());
                            }
                        }
                        break;
                    default:
                        break;
                }
                if (StringUtils.isBlank(imageUrl)) {
                    userInviteRecord.setInvitedToUserImageUrl(defaultHeadUrl);
                } else {
                    userInviteRecord.setInvitedToUserImageUrl(imageUrl);
                }
                userInviteRecord.setInviteTime(userInviteRecord.getCreatedTime());
                userInviteRecord.setInviteTime(userInviteRecord.getCreatedTime());
            }

        }
        return PageableExecutionUtils.getPage(infos, pageRequest, () -> count);
    }

    @Override
    public boolean createActivityInvite(UserInviteCreateVO req) {
        log.info("createActivityInvite 开始创建活动邀请:{}", JSON.toJSONString(req));
        try {
            if (Objects.isNull(req) || Objects.isNull(req.getInvitedByUserInfo()) || StringUtils.isBlank(req.getTargetOpenId())) {
                log.error(":>>> 创建邀请参数错误:邀请人信息或目标用户信息为空");
                throw new BusinessException("创建邀请参数错误:邀请人信息或目标用户信息为空");
            }
            String lockKey = RedisKeyUtil.getCampusUserInviteLock(req.getActivityId(), req.getTargetUser().getId(), req.getInvitedByUserInfo().getId());
            Boolean existKey = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 2L, TimeUnit.SECONDS);
            if (Objects.nonNull(existKey) && !existKey) {
                throw new BusinessException("请勿频繁操作,请稍后重试");
            }
            UserPO targetUser = req.getTargetUser();
            ActivityInfo activityInfo = cacheActivityService.findById(req.getActivityId());
            if (Objects.isNull(activityInfo)) {
                log.error("createActivityInvite 活动:{} 不存在", req.getActivityId());
                return false;
            }
            if (Objects.isNull(targetUser)) {
                log.error(":>>> 分享目标用户不存在,with openId:{}", req.getTargetOpenId());
                throw new BusinessException("创建邀请参数错误:分享目标用户不存在");
            }
            if (req.getInvitedByUserInfo().getId().equals(targetUser.getId())) {
                log.error(":>>> 分享目标用户不能是自己,with openId:{}", req.getTargetOpenId());
                throw new BusinessException("分享目标用户不能是自己");
            }
            if (StringUtils.isBlank(req.getTaskId())) {
                log.error(":>>> 活动任务ID为空,使用默认任务ID");
                if (Objects.isNull(req.getTaskBizType())) {
                    req.setTaskBizType(TaskBizType.INVITE);
                }
                Query queryTask = new Query().addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskBizType").is(req.getTaskBizType()));
                ActivityTaskInfo taskInfo = mongoTemplate.findOne(queryTask, ActivityTaskInfo.class);
                if (Objects.isNull(taskInfo)) {
                    log.error(":>>> 活动:{} 任务为空,", req.getActivityId());
                    return false;
                }
                req.setTaskId(taskInfo.getId());
                req.setShareName(taskInfo.getName());
                log.info(":>>> 任务:{},是否更新邀请榜单:{}", taskInfo.getId(), taskInfo.getUpdateRanking());
                req.setUpdateRanking(taskInfo.getUpdateRanking());
            }
            //判断用户是否被邀请成功过,如果有被邀请成功的记录 就不在创建新的记录,避免用户注销被另外的用户邀请增加贡献值
            Query targetUserQuery = new Query();
            targetUserQuery.addCriteria(Criteria.where("invitedToUserId").is(targetUser.getId()).and("activityId").is(req.getActivityId()).and("joinStatus").is(Boolean.TRUE));
            UserInviteRecord targetUserInviteRecord = mongoTemplate.findOne(targetUserQuery, UserInviteRecord.class);
            if (Objects.nonNull(targetUserInviteRecord)) {
                log.error("createActivityInvite 目标用户已经被邀请成功过 targetUserInviteRecord:{}", targetUserInviteRecord);
                //扫码加贡献值
                doInviteHelp(req, activityInfo);
                return Boolean.TRUE;
            }
            //可能会存在主从问题
            Query query = new Query();
            query.addCriteria(Criteria.where("userId").is(targetUser.getId()));
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
            query.addCriteria(Criteria.where("joined").is(Boolean.TRUE));
            UserParticipateActivityInfo userParticipateActivityInfo = this.mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
            if (Objects.nonNull(userParticipateActivityInfo)) {
                log.error("【邀请用户】邀请用户 -> {} 邀请被邀请用户 -> {} 活动 -> {} {} 已报名过", req.getInvitedByUserInfo().getId(), targetUser.getId(), req.getActivityId(), activityInfo.getType());
                //小程序竞赛无需增加贡献值
                if (!"wx-mini-dreambeat-contest".equals(activityInfo.getType())) {
                    doInviteHelp(req, activityInfo);
                }
                return Boolean.TRUE;
            }
            Query query1 = new Query();
            query1.addCriteria(Criteria.where("invitedToUserId").is(targetUser.getId()).and("invitedByUserId").is(req.getInvitedByUserInfo().getId()).and("activityId").is(req.getActivityId()).and("taskId").is(req.getTaskId()));
            UserInviteRecord exists = mongoTemplate.findOne(query1, UserInviteRecord.class);
            if (Objects.nonNull(exists)) {
                if (!exists.getJoinStatus()) {
                    log.info(":>>> 用户:{} 已经被邀请,直接返回:{}", targetUser.getId(), req.getInvitedByUserInfo().getId());
                    return Boolean.TRUE;
                }
                //扫码加贡献值
                doInviteHelp(req, activityInfo);
                return Boolean.TRUE;
            }
            req.setQa(activityInfo.getHasQa());
            Date date = new Date();
            Update update = new Update();
            update.setOnInsert("createdTime", date);
            update.set("updatedTime", date);
            update.set("invitedByUserOpenId", req.getInvitedByUserInfo().getOpenId());
            update.set("invitedByUserName", req.getInvitedByUserInfo().getNickName());
            update.set("invitedByUserImageUrl", req.getInvitedByUserInfo().getAvatarUrl());
            if (StringUtils.isNotBlank(targetUser.getOpenId())) {
                update.set("invitedToUserOpenId", targetUser.getOpenId());
            }
            if (StringUtils.isNotBlank(targetUser.getNickName())) {
                update.set("invitedToUserName", targetUser.getNickName());
            }
            if (StringUtils.isNotBlank(targetUser.getAvatarUrl())) {
                update.set("invitedToUserImageUrl", targetUser.getAvatarUrl());
            }
            update.set("shareName", req.getShareName());
            update.set("appId", req.getAppId());
            update.set("platform", req.getPlatform());
            update.set("shareType", ShareType.FISSION);
            update.set("extra", req.getExtra());
            if (Objects.nonNull(req.getQa()) && Boolean.TRUE.equals(req.getQa())) {
                update.set("qa", Boolean.TRUE);
            } else {
                update.set("qa", Boolean.FALSE);
            }
            update.set("joinStatus", Boolean.FALSE);
            update.set("inviteTime", date);
            //判断邀请者是否分销者
            DistributorApply distributorApply = distributorApplyService.findByUserId(req.getInvitedByUserInfo().getId(), DistributorApplyStatusEnum.PASS.getValue());
            if (Objects.nonNull(distributorApply)) {
                update.set("inviterDistributor", Boolean.TRUE);
            } else {
                update.set("inviterDistributor", Boolean.FALSE);
            }
            FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
            findAndModifyOptions.upsert(Boolean.TRUE);
            findAndModifyOptions.returnNew(Boolean.TRUE);
            this.mongoTemplate.findAndModify(query1, update, findAndModifyOptions, UserInviteRecord.class);
            return true;
        } catch (BusinessException e) {
            log.error(":>>> 创建用户分享错误:{}", e.getMessage());
            return false;
        } catch (Exception e) {
            log.error(":>>> 创建用户分享错误:{}", e);
            return false;

        }
    }

    @Override
    public QResult createActivityInvite2(UserInviteCreateVO req) {
        log.info("createActivityInvite2 开始创建活动邀请:{}", JSON.toJSONString(req));
        try {
            if (Objects.isNull(req) || Objects.isNull(req.getInvitedByUserInfo()) || StringUtils.isBlank(req.getTargetOpenId())) {
                log.error(":>>> 创建邀请参数错误:邀请人信息或目标用户信息为空");
                throw new BusinessException("创建邀请参数错误:邀请人信息或目标用户信息为空");
            }
            String lockKey = RedisKeyUtil.getCampusUserInviteLock(req.getActivityId(), req.getTargetUser().getId(), req.getInvitedByUserInfo().getId());
            Boolean existKey = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 2L, TimeUnit.SECONDS);
            if (Objects.nonNull(existKey) && !existKey) {
                throw new BusinessException("请勿频繁操作,请稍后重试");
            }
            UserPO targetUser = req.getTargetUser();
            ActivityInfo activityInfo = cacheActivityService.findById(req.getActivityId());
            if (Objects.isNull(activityInfo)) {
                log.error("createActivityInvite2 活动:{} 不存在", req.getActivityId());
                return QResult.success(false);
            }
            if (Objects.isNull(targetUser)) {
                log.error(":>>> 分享目标用户不存在,with openId:{}", req.getTargetOpenId());
                throw new BusinessException("创建邀请参数错误:分享目标用户不存在");
            }
            if (req.getInvitedByUserInfo().getId().equals(targetUser.getId())) {
                log.error(":>>> 分享目标用户不能是自己,with openId:{}", req.getTargetOpenId());
                throw new BusinessException("分享目标用户不能是自己");
            }
            if (StringUtils.isBlank(req.getTaskId())) {
                log.error(":>>> 活动任务ID为空,使用默认任务ID");
                if (Objects.isNull(req.getTaskBizType())) {
                    req.setTaskBizType(TaskBizType.INVITE);
                }
                Query queryTask = new Query().addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskBizType").is(req.getTaskBizType()));
                ActivityTaskInfo taskInfo = mongoTemplate.findOne(queryTask, ActivityTaskInfo.class);
                if (Objects.isNull(taskInfo)) {
                    log.error(":>>> 活动:{} 任务为空,", req.getActivityId());
                    return QResult.success(false);
                }
                req.setTaskId(taskInfo.getId());
                req.setShareName(taskInfo.getName());
                log.info(":>>> 任务:{},是否更新邀请榜单:{}", taskInfo.getId(), taskInfo.getUpdateRanking());
                req.setUpdateRanking(taskInfo.getUpdateRanking());
            }
            //判断用户是否被邀请成功过,如果有被邀请成功的记录 就不在创建新的记录,避免用户注销被另外的用户邀请增加贡献值
            Query targetUserQuery = new Query();
            targetUserQuery.addCriteria(Criteria.where("invitedToUserId").is(targetUser.getId()).and("activityId").is(req.getActivityId()).and("joinStatus").is(Boolean.TRUE));
            UserInviteRecord targetUserInviteRecord = mongoTemplate.findOne(targetUserQuery, UserInviteRecord.class);
            if (Objects.nonNull(targetUserInviteRecord)) {
                log.error("createActivityInvite2 目标用户已经被邀请成功过 targetUserInviteRecord:{}", targetUserInviteRecord);
                //扫码加贡献值
                doInviteHelp(req, activityInfo);
                return QResult.success(Boolean.TRUE);
            }
            //可能会存在主从问题
            Query query = new Query();
            query.addCriteria(Criteria.where("userId").is(targetUser.getId()));
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
            query.addCriteria(Criteria.where("joined").is(Boolean.TRUE));
            UserParticipateActivityInfo userParticipateActivityInfo = this.mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
            if (Objects.nonNull(userParticipateActivityInfo)) {
                log.error("【邀请用户】邀请用户 -> {} 邀请被邀请用户 -> {} 活动 -> {} {} 已报名过", req.getInvitedByUserInfo().getId(), targetUser.getId(), req.getActivityId(), activityInfo.getType());
                //小程序竞赛无需增加贡献值
                if (!"wx-mini-dreambeat-contest".equals(activityInfo.getType())) {
                    doInviteHelp(req, activityInfo);
                }
                return QResult.success(Boolean.TRUE);
            }
            Query query1 = new Query();
            query1.addCriteria(Criteria.where("invitedToUserId").is(targetUser.getId()).and("invitedByUserId").is(req.getInvitedByUserInfo().getId()).and("activityId").is(req.getActivityId()).and("taskId").is(req.getTaskId()));
            UserInviteRecord exists = mongoTemplate.findOne(query1, UserInviteRecord.class);
            if (Objects.nonNull(exists)) {
                if (!exists.getJoinStatus()) {
                    log.info(":>>> 用户:{} 已经被邀请,直接返回:{}", targetUser.getId(), req.getInvitedByUserInfo().getId());
                    return QResult.success(Boolean.TRUE);
                }
                //扫码加贡献值
                doInviteHelp(req, activityInfo);
                return QResult.success(Boolean.TRUE);
            }
            req.setQa(activityInfo.getHasQa());
            Date date = new Date();
            Update update = new Update();
            update.setOnInsert("createdTime", date);
            update.set("updatedTime", date);
            update.set("invitedByUserOpenId", req.getInvitedByUserInfo().getOpenId());
            update.set("invitedByUserName", req.getInvitedByUserInfo().getNickName());
            update.set("invitedByUserImageUrl", req.getInvitedByUserInfo().getAvatarUrl());
            if (StringUtils.isNotBlank(targetUser.getOpenId())) {
                update.set("invitedToUserOpenId", targetUser.getOpenId());
            }
            if (StringUtils.isNotBlank(targetUser.getNickName())) {
                update.set("invitedToUserName", targetUser.getNickName());
            }
            if (StringUtils.isNotBlank(targetUser.getAvatarUrl())) {
                update.set("invitedToUserImageUrl", targetUser.getAvatarUrl());
            }
            update.set("shareName", req.getShareName());
            update.set("appId", req.getAppId());
            update.set("platform", req.getPlatform());
            update.set("shareType", ShareType.FISSION);
            update.set("extra", req.getExtra());
            if (Objects.nonNull(req.getQa()) && Boolean.TRUE.equals(req.getQa())) {
                update.set("qa", Boolean.TRUE);
            } else {
                update.set("qa", Boolean.FALSE);
            }
            update.set("joinStatus", Boolean.FALSE);
            update.set("inviteTime", date);
            //判断邀请者是否分销者
            DistributorApply distributorApply = distributorApplyService.findByUserId(req.getInvitedByUserInfo().getId(), DistributorApplyStatusEnum.PASS.getValue());
            if (Objects.nonNull(distributorApply)) {
                update.set("inviterDistributor", Boolean.TRUE);
            } else {
                update.set("inviterDistributor", Boolean.FALSE);
            }
            FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
            findAndModifyOptions.upsert(Boolean.TRUE);
            findAndModifyOptions.returnNew(Boolean.TRUE);
            this.mongoTemplate.findAndModify(query1, update, findAndModifyOptions, UserInviteRecord.class);
            return QResult.success(Boolean.TRUE);
        } catch (BusinessException e) {
            log.error(":>>> 创建用户分享错误:{}", e.getMessage());
            return QResult.fail(4000, e.getMessage());
        } catch (Exception e) {
            log.error(":>>> 创建用户分享错误:{}", e);
            return QResult.success(false);
        }
    }

    /**
     * 扫码邀请+贡献值
     *
     * @param req
     */
    private void doInviteHelp(UserInviteCreateVO req, ActivityInfo activityInfo) {
        //如果获得不支持
        if (!activityInfo.getInviteHelp()) {
            log.error("doInviteHelp 活动不支持助力 InviteHelp:{}", activityInfo);
            return;
        }
        ActivityTaskInfo taskInfo = this.findActivityTaskInfo(activityInfo.getId(), TaskBizType.INVITE);
        if (Objects.isNull(taskInfo)) {
            log.error("doInviteHelp taskInfo is null");
            return;
        }
        UserPO targetUser = req.getTargetUser();//当前用户
        UserPO invitedByUserInfo = req.getInvitedByUserInfo();//被助力用户
        // 一个用户 一天只能给 3个不同的用户助力  每天0点重置
        //已存在不进行加贡献值
        String lockKey = RedisKeyUtil.getUserHelpLockKey(req.getActivityId(), req.getTaskId(), invitedByUserInfo.getId(), targetUser.getId());
        Boolean existKey = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "1", 24L, TimeUnit.HOURS);
        log.info("doInviteHelp 获取锁 lockKey:{},existKey:{}", lockKey, existKey);
        if (Objects.nonNull(existKey) && !existKey) {
            log.error("doInviteHelp 重复助力 助力用户id:{},被助力用户id:{},活动id:{},lockKey:{}", targetUser.getId(), invitedByUserInfo.getId(), req.getActivityId(), lockKey);
            throw new BusinessException("您已为该用户助力,请勿重复操作");
        }
        //被其他用户助力次数 限制 3次
        String invitedByUserNumberKey = RedisKeyUtil.getUserHelpNumerKey(req.getActivityId(), req.getTaskId(), invitedByUserInfo.getId());
        String userIncrement = stringRedisTemplate.opsForValue().get(invitedByUserNumberKey);
        log.info("doInviteHelp 被其他用户助力 key:{},num:{}", invitedByUserNumberKey, userIncrement);
        if (Objects.nonNull(userIncrement) && Integer.valueOf(userIncrement.toString()) >= 3) {
            log.error("doInviteHelp 用户被助力次数限制 助力用户id:{},被助力用户id:{},活动id:{},次数{}", targetUser.getId(), invitedByUserInfo.getId(), req.getActivityId(), userIncrement);
            throw new BusinessException("每日被他人助力次数已上限,每日被助力3次");
        }
        //用户助力其他人次数 限制 3次
        String targetUserNumberKey = RedisKeyUtil.getUserHelpInviteNumberKey(req.getActivityId(), req.getTaskId(), targetUser.getId());
        String targetUserIncrement = stringRedisTemplate.opsForValue().get(targetUserNumberKey);
        log.info("doInviteHelp 用户助力其他人 key:{},num:{}", invitedByUserNumberKey, userIncrement);
        if (Objects.nonNull(targetUserIncrement) && Integer.valueOf(targetUserIncrement.toString()) >= 3) {
            log.error("doInviteHelp 每日助力人数限制 助力用户id:{},被助力用户id:{},活动id:{},次数{}", targetUser.getId(), invitedByUserInfo.getId(), req.getActivityId(), userIncrement);
            throw new BusinessException("每日给他人助力次数已上限,每日可助力3次");
        }
        //用户助力次数 +1
        Long increment = stringRedisTemplate.opsForValue().increment(targetUserNumberKey, 1);
        if (increment == 1) {//第一次设置过期时间
            stringRedisTemplate.expire(targetUserNumberKey, 24L, TimeUnit.HOURS);
        }
        //被助力次数+1
        increment = stringRedisTemplate.opsForValue().increment(invitedByUserNumberKey, 1);
        if (increment == 1) {//第一次设置过期时间
            stringRedisTemplate.expire(invitedByUserNumberKey, 24L, TimeUnit.HOURS);
        }
        try {
            //重置 贡献值
            taskInfo.setPoints(activityInfo.getInviteHelpValue().doubleValue());
            //更新用户 贡献值
            userActivityTaskRankingService.saveQuantity(invitedByUserInfo, taskInfo, TaskBizType.INVITE_HELP);
            log.info("doInviteHelp 助力成功 助力用户id:{},被助力用户id:{},活动id:{},贡献值:{}", targetUser.getId(), invitedByUserInfo.getId(), req.getActivityId(), activityInfo.getInviteHelpValue());
        } catch (Exception e) {
            log.error("doInviteHelp 更新邀请用户 -> {} 邀请被邀请用户 -> {} 活动 -> {} 助力贡献值错误", req.getInvitedByUserInfo().getId(), targetUser.getId(), req.getActivityId(), e);
        }
    }

    @Override
    public List<ActivityInfo> findByTaskType(Integer taskType, Boolean status) {
        log.info(":>>> 开始获取活动信息,taskType:{},status:{}", taskType, status);
        if (Objects.isNull(taskType) || Objects.isNull(status)) {
            log.error(":>>> 任务类型或状态为空");
            return new ArrayList<>();
        }
        Query query = new Query().addCriteria(Criteria.where("taskType").is(taskType).and("status").is(status));
        List<ActivityInfo> datas = mongoTemplate.find(query, ActivityInfo.class);
        return datas;
    }

    @Override
    public ActivityInfo findDailyAttendanceActivityInfo() {
        List<ActivityInfo> activityInfos = this.findByTaskType(4, Boolean.TRUE);
        if (CollectionUtils.isEmpty(activityInfos)) {
            log.error(":>>> 暂无激活的打卡活动,请联系管理员处理");
            return null;
        }
        return activityInfos.get(0);
    }

    @Override
    public ActivityTaskInfo findActivityTaskInfo(String activityId, TaskBizType taskBizType) {
        log.info(":>>> 开始获取活动任务:{},{}", activityId, taskBizType);
        if (StringUtils.isBlank(activityId) || Objects.isNull(taskBizType)) {
            log.error("活动ID或业务类型为空");
            throw new BusinessException("活动ID或业务类型为空");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("taskBizType").is(taskBizType));
        // 2. 按 createTime 降序排序（最新的排在最前面）
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));
        // 3. 限制只返回第一条数据
        query.limit(1);
        ActivityTaskInfo activityTaskInfo = mongoTemplate.findOne(query, ActivityTaskInfo.class);
        return activityTaskInfo;
    }

    @Override
    public ActivityTaskInfo findActivityTaskInfo(String id) {
        log.info(":>>> 开始查找活动任务:{}", id);
        if (StringUtils.isBlank(id)) {
            log.info(":>>> 查找活动任务ID 参数错误,ID为空");
            throw new BusinessException("查找活动任务ID 参数错误,ID为空");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, ActivityTaskInfo.class);
    }

    @Override
    public Integer getVolunteerDuration(String userId) {
        log.info(":>>> 开始获取用户:{} 志愿时长", userId);
        if (StringUtils.isBlank(userId)) {
            log.error(":>>> 获取用户志愿时长参数错误");
            throw new BusinessException("获取用户志愿时长参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("accomplishTime").ne(null));
        List<UserParticipateActivityInfo> datas = mongoTemplate.find(query, UserParticipateActivityInfo.class);
        if (CollectionUtils.isEmpty(datas)) {
            return 0;
        }
        Integer duration = 0;
        for (UserParticipateActivityInfo u : datas) {
            Query query1 = new Query().addCriteria(Criteria.where("id").is(u.getActivityId()));
            ActivityInfo activityInfo = mongoTemplate.findOne(query1, ActivityInfo.class);
            if (Objects.nonNull(activityInfo) && Objects.nonNull(activityInfo.getDuration())) {
                duration = duration + activityInfo.getDuration();
            }
        }
        return duration;
    }

    @Override
    public boolean favoriteActivity(String userId, String activityId, Boolean favorited) {
        log.info(":>>> 开始处理收藏/取消收藏活动:{},{},{}", userId, activityId, favorited);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(activityId) || Objects.isNull(favorited)) {
            log.error(":>>> 处理活动收藏参数错误");
            throw new BusinessException("处理活动收藏参数错误");
        }
        Date date = new Date();
        ActivityInfo activityInfo = this.findOne(activityId);
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        UserParticipateActivityInfo up = mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        // 收藏
        if (Boolean.TRUE.equals(favorited)) {
            if (Objects.isNull(up)) {
                up = new UserParticipateActivityInfo();
                up.setUserId(userId);
                up.setActivityId(activityId);
                up.setActivityInfo(activityInfo);
                up.setCreatedTime(date);
                up.setFavorited(true);
                up.setFavoritedTime(date);
                //报名状态,0:未开始,1:未报名,2:已报名,3:已完成
                up.setJoined(true);
                mongoTemplate.insert(up);
                return true;
            }
            if (Boolean.TRUE.equals(up.getFavorited())) {
                return true;
            }
            up.setFavorited(true);
            up.setFavoritedTime(date);
            up.setUpdatedTime(date);
            mongoTemplate.save(up);
            return true;
        }
        // 取消收藏
        else {
            if (Objects.isNull(up)) {
                log.info(":>>> 数据不存在");
                return false;
            }
            if (Boolean.FALSE.equals(up.getFavorited())) {
                log.info(":>>> 活动:{} 已经被用户收藏:{}", activityId, userId);
                return true;
            }
            up.setFavorited(false);
            up.setFavoritedTime(null);
            up.setUpdatedTime(date);
            mongoTemplate.save(up);
            return true;

        }
    }

    @Override
    public List<ActivityQaInfoVO> getQa(ActivityQaInfoVO req) {
        log.info(":>>> 开始获取活动问题:{}", JSON.toJSONString(req));
        if (Objects.isNull(req)) {
            log.error(":>>> 获取活动问题参数错误");
            throw new BusinessException("获取活动问题参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        if (StringUtils.isNotBlank(req.getActivityQaInfoId())) {
            query.addCriteria(Criteria.where("id").is(req.getActivityQaInfoId()));
        }
        if (Objects.nonNull(req.getNo())) {
            query.addCriteria(Criteria.where("no").is(req.getNo()));
        }
        ActivityQaInfo activityQaInfo = mongoTemplate.findOne(query, ActivityQaInfo.class);
        if (Objects.isNull(activityQaInfo)) {
            log.info(":>>> 活动试卷不存在:{}", req.getActivityId());
            return new ArrayList<>();
        }
        Query queryQuestion = new Query().addCriteria(Criteria.where("activityQaInfoId").is(req.getActivityQaInfoId()));
//        queryQuestion.with(new Sort(new Sort.Order(Sort.Direction.ASC, "priority")));
        Sort sort = Sort.by(Sort.Direction.ASC, "priority");
        queryQuestion.with(sort);
        List<ActivityQuestionInfo> questionInfos = mongoTemplate.find(queryQuestion, ActivityQuestionInfo.class);
        if (CollectionUtils.isEmpty(questionInfos)) {
            return new ArrayList<>();
        }
        Boolean randomQa = activityQaInfo.getRandomQa();
        //随机答题
        if (randomQa) {
            List<ActivityQuestionInfo> questionInfoList = new ArrayList<>();
            //随机单选题数量
            Integer randomRadioQaCount = activityQaInfo.getRandomRadioQaCount();
            List<ActivityQuestionInfo> randomRadioQaList = questionInfos.stream().filter(questionInfo -> questionInfo.getType() == 1).collect(Collectors.toList());
            randomQuestionInfo(randomRadioQaCount, questionInfoList, randomRadioQaList);
            //随机多选题数量
            Integer randomMultiQaCount = activityQaInfo.getRandomMultiQaCount();
            List<ActivityQuestionInfo> randomMultiQaList = questionInfos.stream().filter(questionInfo -> questionInfo.getType() == 0).collect(Collectors.toList());
            randomQuestionInfo(randomMultiQaCount, questionInfoList, randomMultiQaList);
            Integer[] index = {1};
            List<ActivityQuestionInfo> orderQuestionInfoList = questionInfoList.stream().peek(questionInfo -> questionInfo.setPriority(index[0]++)).collect(Collectors.toList());
            return orderQuestionInfoList.stream().map(orderQuestionInfo -> {
                ActivityQaInfoVO activityQaInfoVO = new ActivityQaInfoVO();
                activityQaInfoVO.setActivityId(req.getActivityId());
                activityQaInfoVO.setQuestion(orderQuestionInfo);
                activityQaInfoVO.setUserId(req.getUserId());
                activityQaInfoVO.setQaSystemNumber(activityQaInfo.getQaSystemNumber());
                List<ActivityAnswerInfo> answerInfoList = findByQuestionId(orderQuestionInfo.getId());
                orderQuestionInfo.setAnswerInfos(answerInfoList.stream().map(activityAnswerInfo -> {
                    activityAnswerInfo.setAnswered(Boolean.FALSE);
                    return activityAnswerInfo;
                }).collect(Collectors.toList()));
                activityQaInfoVO.setAnswers(orderQuestionInfo.getAnswerInfos().stream().sorted(Comparator.comparing(ActivityAnswerInfo::getPriority)).collect(Collectors.toList()));
                return activityQaInfoVO;
            }).collect(Collectors.toList());
        }
        log.info(":>>> 试卷:{},问题个数:{}", activityQaInfo.getName(), questionInfos.size());
        Integer qaNumber = 0;
        List<ActivityQaInfoVO> result = new ArrayList<>();
        for (ActivityQuestionInfo questionInfo : questionInfos) {
            ActivityQaInfoVO activityQaInfoVO = new ActivityQaInfoVO();
            activityQaInfoVO.setActivityId(req.getActivityId());
            activityQaInfoVO.setQuestion(questionInfo);
            activityQaInfoVO.setUserId(req.getUserId());
            activityQaInfoVO.setPriority(qaNumber++);
            activityQaInfoVO.setQaSystemNumber(activityQaInfo.getQaSystemNumber());
            Query queryAn = new Query().addCriteria(Criteria.where("activityQuestionId").is(questionInfo.getId()));
//            queryAn.with(new Sort(new Sort.Order(Sort.Direction.ASC, "priority")));
            Sort sortNN = Sort.by(Sort.Direction.ASC, "priority");
            queryAn.with(sortNN);
            List<ActivityAnswerInfo> ans = mongoTemplate.find(queryAn, ActivityAnswerInfo.class);
            questionInfo.setAnswerInfos(ans);
            activityQaInfoVO.setAnswers(ans);
            result.add(activityQaInfoVO);
        }
        return result;
    }

    private List<ActivityAnswerInfo> findByQuestionId(String questionId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("activityQuestionId").is(questionId));
        return this.mongoTemplate.find(query, ActivityAnswerInfo.class);
    }


    private void randomQuestionInfo(Integer randomCount, List<ActivityQuestionInfo> questionInfoList, List<ActivityQuestionInfo> randomQuestionInfoList) {
        if (CollectionUtils.isEmpty(randomQuestionInfoList)) {
            return;
        }
        Collections.shuffle(randomQuestionInfoList);
        if (randomCount >= 1) {
            log.info("随机生成题库 -> {} 随机数-> {}", randomQuestionInfoList.size(), randomCount);
            if (randomQuestionInfoList.size() > randomCount) {
                questionInfoList.addAll(randomQuestionInfoList.subList(0, randomCount));
                return;
            }
        }
        questionInfoList.addAll(randomQuestionInfoList);
    }

    @Override
    public ActivityQaInfo getQaInfo(ActivityQaInfoVO req) {
        log.info(":>>> 开始获取活动问题:{}", JSON.toJSONString(req));
        if (Objects.isNull(req)) {
            log.error(":>>> 获取活动问题参数错误");
            throw new BusinessException("获取活动问题参数错误");
        }
        ActivityInfo activityInfo = findOne(req.getActivityId());
        Query query = new Query().addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        if (StringUtils.isNotBlank(req.getActivityQaInfoId())) {
            query.addCriteria(Criteria.where("id").is(req.getActivityQaInfoId()));
        }
        if (Objects.nonNull(req.getNo())) {
            query.addCriteria(Criteria.where("no").is(req.getNo()));
        }
        ActivityQaInfo activityQaInfo = mongoTemplate.findOne(query, ActivityQaInfo.class);

        if (Objects.isNull(activityQaInfo)) {
            log.info(":>>> 活动试卷不存在:{}", req.getActivityId());
            throw new BusinessException("活动问题信息不存在");
        }
        if (Objects.nonNull(activityQaInfo)) {
            if (Objects.nonNull(activityInfo)) {
                Long dianZanNum = this.getJoinNum(activityInfo.getId(), activityInfo.getInitJoinNum(), true);
                Long dianZanNum0 = activityVideoService.getDianZanNum(activityInfo.getId(), activityQaInfo.getId());
                dianZanNum = dianZanNum + dianZanNum0;
                Long randomViewNum = this.getViewNum(activityInfo.getId(), activityInfo.getInitJoinNum(), true);
                activityQaInfo.setBrowseNum(randomViewNum.intValue());

                activityQaInfo.setDianZanNum(dianZanNum.intValue());
            }
        }
        if (StringUtils.isNotBlank(req.getActivityQaInfoId())) {
            UserQaInfo userQaInfo = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("userId").is(req.getUserId()).and("activityQaInfoId").is(req.getActivityQaInfoId())), UserQaInfo.class);
            if (Objects.nonNull(userQaInfo)) {
                activityQaInfo.setMaxScore(userQaInfo.getMaxScore());
                activityQaInfo.setRetryQaNum(userQaInfo.getReTryQaNum());
                activityQaInfo.setCaName(userQaInfo.getCaName());
            } else {
                activityQaInfo.setMaxScore(0D);
                activityQaInfo.setRetryQaNum(activityQaInfo.getRetryQaNum());
                activityQaInfo.setCaName("暂无证书");
            }
        }
        if (StringUtils.isNotBlank(activityInfo.getQaDetailBeforeSignUp())) {
            activityQaInfo.setDetail("");
            activityQaInfo.setDetail(activityInfo.getQaDetailBeforeSignUp());
        }
        activityQaInfo.setSignUpBeforeCa(activityInfo.getSignUpBeforeCa());
        activityQaInfo.setHasMultiQa(activityInfo.getHasMultiQa());
        activityQaInfo.setType(activityInfo.getType());
        return activityQaInfo;
    }

    @Override
    public UserParticipateActivityInfo doQa(UserDoQaVO req) {
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getUserId()) || CollectionUtils.isEmpty(req.getQas())) {
            log.error(":>>> 答题参数错误");
            throw new BusinessException("答题参数错误");
        }
        if ("qq-h5".equals(req.getPlatform())) {
            throw new BusinessException("QQ平台暂不支持活动报名");
        }
        ActivityInfo activityInfo = this.findOne(req.getActivityId());
        ActivityQaInfo activityQaInfo = this.mongoTemplate.findById(req.getActivityQaInfoId(), ActivityQaInfo.class);
        Query queryP = new Query().addCriteria(Criteria.where("userId").is(req.getUserId()).and("activityId").is(req.getActivityId()));
        long count = this.mongoTemplate.count(queryP, UserParticipateActivityInfo.class);
        //兼容老数据继续刷题用户
        if (count > activityQaInfo.getTotalQaNum()) {
            throw new BusinessException("对不起答题" + activityQaInfo.getTotalQaNum() + "次已用完");
        }
        UserParticipateActivityInfo participateActivityInfo = null;
//        UserParticipateActivityInfo participateActivityInfo = mongoTemplate.findOne(queryP,
//                UserParticipateActivityInfo.class);
        List<UserParticipateActivityInfo> ups = mongoTemplate.find(queryP, UserParticipateActivityInfo.class);
        if (!CollectionUtils.isEmpty(ups)) {
            for (UserParticipateActivityInfo up : ups) {
                if (Boolean.TRUE.equals(up.getJoined())) {
                    participateActivityInfo = up;
                    break;
                }
            }
        }
        Double score = this.computeQaScore(req);
        log.info(":>>> 用户:{},答题的最终得分为:{},活动通过分数:{}", req.getUserId(), score, activityInfo.getPassQaScore());
        if (Objects.isNull(participateActivityInfo)) {
            log.info(":>>> 用户:{} 未报名:{} 活动", req.getUserId(), req.getActivityId());
            // 活动为先答题后报名
            if ("0".equals(activityInfo.getQaMode())) {
                participateActivityInfo = new UserParticipateActivityInfo();
                participateActivityInfo.setActivityId(req.getActivityId());
                participateActivityInfo.setUserId(req.getUserId());
                participateActivityInfo.setCreatedTime(new Date());
                participateActivityInfo.setJoined(false);
                participateActivityInfo.setTotalQaNum(activityQaInfo.getTotalQaNum());
                participateActivityInfo.setPassQaScore(activityQaInfo.getPassQaScore());
                participateActivityInfo.setCurrentQaScore(score);
                participateActivityInfo.setQaScore(score);
                participateActivityInfo.setUnionId(req.getUserPO().getUnionId());
                participateActivityInfo.setOpenId(req.getUserPO().getOpenId());
                participateActivityInfo.setAvatarUrl(req.getUserPO().getAvatarUrl());
                participateActivityInfo.setAppId(req.getUserPO().getAppId());
                participateActivityInfo.setPlatform(req.getUserPO().getCurrentPlatform());
                participateActivityInfo = mongoTemplate.insert(participateActivityInfo);
                log.info(":>>> 用户:{} 未报名:{} 活动,创建报名信息:{}", req.getUserId(), req.getActivityId(), JSON.toJSONString(participateActivityInfo));
            } else {
                log.error(":>>> 用户:{} 未报名:{} 活动,不能答题", req.getUserId(), req.getActivityId());
                throw new BusinessException("用户未报名活动,不能参与答题");
            }
        }
        if (Boolean.TRUE.equals(activityInfo.getQaAccumulation()) && Boolean.TRUE.equals(participateActivityInfo.getPassed())) {
            log.error(":>>> 活动配置答题不可累加,用户已经通过答题:{},请不要重复答题", req.getUserId());
            return participateActivityInfo;
        } else {
            if (Boolean.TRUE.equals(activityInfo.getQaLimit()) && participateActivityInfo.getReTryQaNum() < 0) {
                log.error(":>>> 用户无答题国青币,请邀请用户", req.getUserId());
                throw new BusinessException("您已经答题" + participateActivityInfo.getTotalQaNum() + "次,请邀请好友助力!");
            }
        }
        if (participateActivityInfo.getReTryQaNum() > activityQaInfo.getTotalQaNum()) {
            throw new BusinessException("对不起答题" + participateActivityInfo.getTotalQaNum() + "次已用完");
        }
        if (score.compareTo(participateActivityInfo.getPassQaScore()) != -1) {
            participateActivityInfo.setQaScore(score);
        }
        participateActivityInfo.setReTryQaNum(participateActivityInfo.getReTryQaNum() + 1);
        if (Objects.nonNull(activityQaInfo.getPassQaScore()) && participateActivityInfo.getQaScore().compareTo(activityQaInfo.getPassQaScore()) != -1) {
            // 通过
            participateActivityInfo.setPassed(true);
            if (Boolean.TRUE.equals(activityInfo.getDoQaHasCa())) {
                log.info(":>>> 活动配置了答题可获得证书:{}", activityInfo.getId());
                ActivityQaRule activityQaRule = activityQaRuleService.match(activityInfo.getId(), null, score.intValue());
                if (Objects.isNull(activityQaRule)) {
                    participateActivityInfo.setHasCa(false);
                    participateActivityInfo.setCaName("暂无证书");
                } else {
                    participateActivityInfo.setHasCa(true);
                    participateActivityInfo.setCaName(activityQaRule.getCaName());
                }
            }

        } else {
            // 未通过
            if (!Boolean.TRUE.equals(participateActivityInfo.getPassed())) {
                participateActivityInfo.setPassed(false);
            }
        }
        //重复答题情况【报名后如果第1次以上答题未通过】如果答题通过则加
        if (participateActivityInfo.getJoined() && !participateActivityInfo.getAccumulateQ() && score.compareTo(activityQaInfo.getPassQaScore()) != -1) {
            if (activityInfo.getAccumulate()) {
                log.info(":>>> 开始累加:{},用户:{},积分值", activityInfo.getId(), req.getUserId());
                ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.QA.name());
                if (Objects.nonNull(taskRule)) {
                    if ("h5++".equals(activityInfo.getType())) {
                        //增加活力值和活力值记录
                        UserActivityPointDetail userActivityPointDetail = new UserActivityPointDetail();
                        userActivityPointDetail.setAction("add");
                        userActivityPointDetail.setActivityId(activityQaInfo.getActivityId());
                        userActivityPointDetail.setBizDesc("报名成功");
                        userActivityPointDetail.setComments("报名成功" + taskRule.getPoints().intValue());
                        userActivityPointDetail.setBizType("qa");
                        userActivityPointDetail.setOptDate(new Date());
                        userActivityPointDetail.setPoints(taskRule.getPoints().intValue());
                        userActivityPointDetail.setUserId(req.getUserId());
                        userActivityPointDetail.setUserPO(req.getUserPO());
                        userActivityPointDetailService.create(userActivityPointDetail);
                        //增加省排行榜
                        userActivityPointRankingProvinceService.updatePoint(req.getUserPO(), activityInfo.getId(), taskRule.getPoints().intValue());
                    } else {
                        ActivityTaskInfo taskInfo = this.findActivityTaskInfo(req.getActivityId(), TaskBizType.INVITE);
                        //重置 贡献值
                        taskInfo.setPoints(taskRule.getPoints());
                        //更新用户 贡献值
                        userActivityTaskRankingService.saveQuantity(req.getUserPO(), taskInfo, TaskBizType.QA);
                    }
                    participateActivityInfo.setAccumulateQ(true);
                    participateActivityInfo.setUpdatedTime(new Date());
                }

            }
        }
        participateActivityInfo.setCurrentQaScore(score);
        participateActivityInfo.setUpdatedTime(new Date());
        participateActivityInfo = mongoTemplate.save(participateActivityInfo);
        participateActivityInfo.setQaScore(score);
        if (Objects.nonNull(activityQaInfo.getPassQaScore()) && (score.intValue() >= activityQaInfo.getPassQaScore())) {
            participateActivityInfo.setPassed(Boolean.TRUE);
        } else {
            participateActivityInfo.setPassed(Boolean.FALSE);
        }
        participateActivityInfo.setPassQaScore(activityQaInfo.getPassQaScore());
        try {
            UserQaMqMessageReq userQaMqMessageReq = new UserQaMqMessageReq();
            userQaMqMessageReq.setUserId(participateActivityInfo.getUserId());
            userQaMqMessageReq.setUserName(req.getUserPO().getNickName());
            userQaMqMessageReq.setActivityId(activityInfo.getId());
            userQaMQService.sendUserQa(userQaMqMessageReq);
        } catch (Exception e) {
            log.error("用户->{} 答题 ->{} 同步消息错误", participateActivityInfo.getMobile(), req.getActivityQaInfoId());
            return participateActivityInfo;
        }
        //增加答题记录
        UserQaInfo userQaInfo = new UserQaInfo();
        userQaInfo.setActivityId(activityInfo.getId());
        userQaInfo.setActivityName(activityInfo.getName());
        userQaInfo.setNo(activityQaInfo.getNo());
        userQaInfo.setAccumulateQ(participateActivityInfo.getAccumulateQ());
        userQaInfo.setActivityQaInfoId(activityQaInfo.getId());
        userQaInfo.setQaScore(score);
        userQaInfo.setTotalQaNum(activityQaInfo.getTotalQaNum());
        userQaInfo.setUserId(req.getUserId());
        userQaInfoService.create(userQaInfo);
        return participateActivityInfo;
    }

    @Override
    public ActivityRewadDomain getReward(String activityId, String userId, String taskBizType) {
        log.info(":>>> 开始获取奖励 activityId:{},userId:{}", activityId, userId);

        if (StringUtils.isBlank(activityId) || StringUtils.isBlank(userId)) {
            log.error(":>>> 获取活动奖励错误:参数错误->活动ID或用户ID为空");
            throw new BusinessException("获取活动奖励错误");
        }
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        if (Objects.isNull(activityInfo)) {
            log.error(":>>> 活动:{} 不存在", activityId);
            throw new BusinessException("活动信息不存在");
        }
        ActivityRewadDomain res = new ActivityRewadDomain();
        res.setPreOrderDesc(activityInfo.getPreOrderDesc());
        res.setActivityId(activityId);
        Query query = new Query().addCriteria(Criteria.where("id").is(userId));
        UserPO userPO = mongoTemplate.findOne(query, UserPO.class);
        if (Objects.isNull(userPO)) {
            log.error(":>>> 用户:{} 不存在", userId);
            throw new BusinessException("用户不存在");
        }
        if (Boolean.TRUE.equals(userPO.getMemberShiped())) {
            res.setMemberShiped(true);
            res.setRemainedNum(userPO.getRemainedNum() == null ? 5 : userPO.getRemainedNum());
        } else {
            res.setMemberShiped(false);
            res.setRemainedNum(5);
        }
        res.setRemainedNum(userPO.getRemainedNum());
        // 状态,0:待发布,1:已发布,2:已停用
        Query queryMemberShip = new Query().addCriteria(Criteria.where("status").is(1));
        MemberShipInfo memberShipInfo = mongoTemplate.findOne(queryMemberShip, MemberShipInfo.class);
        if (Objects.nonNull(memberShipInfo)) {
            res.setMemberShipInfo(memberShipInfo);
        }
        // TODO:查询已经发放的奖励
        Query queryReward = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        List<UserActivityReward> rewards = mongoTemplate.find(queryReward, UserActivityReward.class);
        List<String> caIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(rewards)) {
            for (UserActivityReward ud : rewards) {
                caIds.add(ud.getCaInfoId());
            }
            Query queryCa = new Query().addCriteria(Criteria.where("id").in(caIds));
            List<CaInfo> caInfos = mongoTemplate.find(queryCa, CaInfo.class);
            res.setCaInfos(caInfos);
        }
        TaskBizType taskBizTypeEnum = TaskBizType.valueOf(taskBizType);

        Query query1 = new Query().addCriteria(Criteria.where("mobile").is(userPO.getMobile()));
        ActivityUserRecord activityUserRecord = mongoTemplate.findOne(query1, ActivityUserRecord.class);
        if (Objects.nonNull(activityUserRecord)) {
            Query query2 = new Query();
            if (taskBizTypeEnum.equals(TaskBizType.INVITE)) {
                if (StringUtils.isNotBlank(activityUserRecord.getCaLevel())) {
                    query2.addCriteria(Criteria.where("level").is(activityUserRecord.getCaLevel()));

                }
            }
            if (taskBizTypeEnum.equals(TaskBizType.QA)) {
                if (StringUtils.isNotBlank(activityUserRecord.getCaLevel())) {
                    query2.addCriteria(Criteria.where("level").is(activityUserRecord.getCaLevel()));

                }
            }
            List<CaInfo> caInfos = mongoTemplate.find(query2, CaInfo.class);
            if (!CollectionUtils.isEmpty(caInfos)) {
                res.getCaInfos().addAll(caInfos);
            }
        }
        log.error(":>>> 领取奖励的详情:{}", JSON.toJSONString(res));
        return res;
    }

    @Override
    public boolean isGetReward(String activityId, String userId) {
        log.info(":>>> 检查用户:{}, 活动:{} 是否领取奖励", userId, activityId);

        if (StringUtils.isBlank(activityId) || StringUtils.isBlank(userId)) {
            log.error(":>>> 用户领取奖励错误:参数错误");
            return false;
//            throw new BusinessException("用户领取奖励参数错误");
        }
        try {
            Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("userId").is(userId).and("rewardReceived").is(Boolean.TRUE));
            boolean exist = mongoTemplate.exists(query, UserActivityReward.class);
            log.info(":>>> 用户:{},活动:{},领取状态:{}", userId, activityId, exist);
            return exist;
        } catch (Exception e) {
            log.error(":>>> 用户是否领取奖励错误:{}", e);
            return false;

        }

    }

    @Override
    public WechatH5PayConfigDomain getPayConfig(UserPO userPO, String url, String nonce_str, String timestampStr) {
        log.info(":>>> 开始获取JS-SDK config配置:{},{},{},{}", JSON.toJSONString(userPO), url, nonce_str, timestampStr);
        Date date = new Date();
        if (StringUtils.isBlank(timestampStr)) {

            timestampStr = date.getTime() + "";
            nonce_str = timestampStr;
            log.info(":>>> 时间戳为空:取当地时间,{},{}", timestampStr, nonce_str);
        }
        if (StringUtils.isBlank(url)) {
            log.error(":>>> url 为空");
            url = platformConfigService.getBizFrontPayDomain() + "/h5/";
            log.info(":>>> 配置的Url :{}", url);
        }
        // url = platformConfigService.getBizFrontPayDomain() + "/h5/#/pages/activity-reward";
        log.info(":>>> JS SDK url:{}", url);
        /**
         * 签名生成规则如下：参与签名的字段包括noncestr（随机字符串）, 有效的jsapi_ticket, timestamp（时间戳）,
         * url（当前网页的URL，不包含#及其后面部分） 。对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）后，
         * 使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1。
         * 这里需要注意的是所有参数名均为小写字符。对string1作sha1加密，字段名和字段值都采用原始值，不进行URL 转义。
         *
         * 即signature=sha1(string1)。 示例：
         *
         */
        Query queryConfig = new Query().addCriteria(Criteria.where("appId").is(userPO.getAppId()));
        WechatConfigInfo configInfo = mongoTemplate.findOne(queryConfig, WechatConfigInfo.class);
        if (Objects.isNull(configInfo)) {
            log.error(":>>> 应用:{} 配置错误", userPO.getAppId());
            throw new BusinessException("公众号:{} 无支付配置");
        }
        String jsApiTicket = wechatH5Service.getJsapiTicket(userPO.getAppId());
        String string1;
        String signature = "";
        //注意这里参数名必须全部小写，且必须有序

        string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonce_str + "&timestamp=" + timestampStr + "&url=" + url;
        HashMap<String, String> toDo = new HashMap<>();
        toDo.put("jsapi_ticket", jsApiTicket);
        toDo.put("nonceStr", nonce_str);
        toDo.put("timestamp", "" + timestampStr);
        toDo.put("url", url);
        log.info(":>>> SHA1加密前:{}", string1);
        try {
            signature = WXPayUtil.generateSignature(toDo, configInfo.getDesc(), WXPayConstants.SignType.MD5);
        } catch (Exception e) {
            log.info(":>>> 生成MD5错误:{}", e);
        }
        log.info(":>>> SHA1加密后:{}", signature);
        WechatH5PayConfigDomain domain = new WechatH5PayConfigDomain();
        domain.setAppId(userPO.getAppId());
        domain.setSignature(signature);
        domain.setNonceStr(nonce_str);
        domain.setTimestamp(timestampStr);
        List<String> jsApiList = new ArrayList<>();
        jsApiList.add("chooseWXPay");
        domain.setJsApiList(jsApiList);
        log.info(":>>> 返回微信JSSDK:{}", JSON.toJSONString(domain));
        return domain;
    }

    @Override
    public WechatH5PayConfigDomain getShareConfig(UserPO userPO, String url) {
        log.info(":>>> 开始获取JS-SDK config配置:{},{}", JSON.toJSONString(userPO), url);
        Date date = new Date();

        String timestampStr = date.getTime() / 1000 + "";
        String nonce_str = timestampStr;
        log.info(":>>> 时间戳为空:取当地时间,{},{}", timestampStr, nonce_str);

        if (StringUtils.isBlank(url)) {
            log.error(":>>> url 为空");
            url = platformConfigService.getBizFrontDomain() + "/h5/";
            log.info(":>>> 配置的Url :{}", url);
        }
        log.info(":>>> JS SDK url:{}", url);
        /**
         * 签名生成规则如下：参与签名的字段包括noncestr（随机字符串）, 有效的jsapi_ticket, timestamp（时间戳）,
         * url（当前网页的URL，不包含#及其后面部分） 。对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）后，
         * 使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1。
         * 这里需要注意的是所有参数名均为小写字符。对string1作sha1加密，字段名和字段值都采用原始值，不进行URL 转义。
         *
         * 即signature=sha1(string1)。 示例：
         *
         */
        Query queryConfig = new Query().addCriteria(Criteria.where("appId").is(userPO.getAppId()));
        WechatConfigInfo configInfo = mongoTemplate.findOne(queryConfig, WechatConfigInfo.class);
        if (Objects.isNull(configInfo)) {
            log.error(":>>> 应用:{} 配置错误", userPO.getAppId());
            throw new BusinessException("公众号:{} 无支付配置");
        }
        String jsApiTicket = wechatH5Service.getJsapiTicket(userPO.getAppId());
        String string1;
        String signature = "";
        //注意这里参数名必须全部小写，且必须有序

        string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonce_str + "&timestamp=" + timestampStr + "&url=" + url;
        try {
            signature = DigestUtils.sha1Hex(string1);
            signature = signature.toLowerCase();
            log.info(":>>> SHA1加密前:{},加密后:{}", string1, signature);
        } catch (Exception e) {
            log.info(":>>> 生成HMAC错误:{}", e);
        }
        WechatH5PayConfigDomain domain = new WechatH5PayConfigDomain();
        domain.setAppId(userPO.getAppId());
        domain.setSignature(signature);
        domain.setNonceStr(nonce_str);
        domain.setTimestamp(timestampStr);
        List<String> jsApiList = new ArrayList<>();
        jsApiList.add("chooseWXPay");
        jsApiList.add("onMenuShareAppMessage");
        jsApiList.add("onMenuShareTimeline");
        jsApiList.add("hideOptionMenu");
        jsApiList.add("showOptionMenu");
        jsApiList.add("updateAppMessageShareData");
        jsApiList.add("updateTimelineShareData");
        domain.setJsApiList(jsApiList);
        log.info(":>>> 返回微信JSSDK:{}", JSON.toJSONString(domain));
        return domain;
    }

    @Override
    public WechatH5PayConfigDomain getJsSdkConfigByAppId(String appId, String url) {
        log.info(":>>> 开始获取JS-SDK config配置:{},{}", appId, url);
        Date date = new Date();
        String timestampStr = date.getTime() / 1000 + "";
        String nonce_str = timestampStr;
        log.info(":>>> 时间戳为空:取当地时间,{},{}", timestampStr, nonce_str);
        if (StringUtils.isBlank(url)) {
            log.error(":>>> url 为空");
            url = platformConfigService.getBizFrontDomain() + "/h5/";
            log.info(":>>> 配置的Url :{}", url);
        }
        log.info(":>>> JS SDK url:{}", url);
        /**
         * 签名生成规则如下：参与签名的字段包括noncestr（随机字符串）, 有效的jsapi_ticket, timestamp（时间戳）,
         * url（当前网页的URL，不包含#及其后面部分） 。对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）后，
         * 使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1。
         * 这里需要注意的是所有参数名均为小写字符。对string1作sha1加密，字段名和字段值都采用原始值，不进行URL 转义。
         *
         * 即signature=sha1(string1)。 示例：
         *
         */
        Query queryConfig = new Query().addCriteria(Criteria.where("appId").is(appId));
        WechatConfigInfo configInfo = mongoTemplate.findOne(queryConfig, WechatConfigInfo.class);
        if (Objects.isNull(configInfo)) {
            log.error(":>>> 应用:{} 配置错误", appId);
            throw new BusinessException("公众号:{} 无支付配置");
        }
        String jsApiTicket = wechatH5Service.getJsapiTicket(appId);
        String string1;
        String signature = "";
        //注意这里参数名必须全部小写，且必须有序

        string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonce_str + "&timestamp=" + timestampStr + "&url=" + url;
        try {
            signature = DigestUtils.sha1Hex(string1);
            signature = signature.toLowerCase();
            log.info(":>>> SHA1加密前:{},加密后:{}", string1, signature);
        } catch (Exception e) {
            log.info(":>>> 生成HMAC错误:{}", e);
        }
        WechatH5PayConfigDomain domain = new WechatH5PayConfigDomain();
        domain.setAppId(appId);
        domain.setSignature(signature);
        domain.setNonceStr(nonce_str);
        domain.setTimestamp(timestampStr);
        List<String> jsApiList = new ArrayList<>();
        jsApiList.add("chooseWXPay");
        jsApiList.add("onMenuShareAppMessage");
        jsApiList.add("onMenuShareTimeline");
        jsApiList.add("hideOptionMenu");
        jsApiList.add("showOptionMenu");
        jsApiList.add("updateAppMessageShareData");
        jsApiList.add("updateTimelineShareData");
        domain.setJsApiList(jsApiList);
        log.info(":>>> 返回微信JSSDK:{},appId:{}", JSON.toJSONString(domain), appId);
        return domain;
    }

    @Override
    public String exportAllUser(String activityId, String optName, String userId, HttpServletResponse response) {
        log.info(":>>> 开始导出活动:{} 报名用户", optName);
        Query query = new Query().addCriteria(Criteria.where("joined").is(Boolean.TRUE));
        if (StringUtils.isNotBlank(activityId)) {
            query.addCriteria(Criteria.where("activityId").is(activityId));
            query.addCriteria(Criteria.where("inBlackList").ne(true));
        }
//        Long count = mongoTemplate.count(query, UserParticipateActivityInfo.class);
        Long count = userUpInfoService.getJoinedCount(activityId);
        log.info(":>>> 活动报名信息:{}", count);
        FileExportTask fileExportTask = new FileExportTask();
        fileExportTask.setToken(optName);
        fileExportTask.setBizType("2");
        fileExportTask.setStatus(0);
        fileExportTask.setOptUser(optName);
        fileExportTask.setOptUserId(userId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(new Date());
        String fileName = "活动报名信息-" + count + "条-" + dateStr;
        String f = fileName + System.currentTimeMillis() / 1000 + ".xlsx";
        fileExportTask.setFileName(f);
        fileExportTask.setNum(count.intValue());
        fileExportTask.setDesc("活动报名信息");
        String re = fileExportTaskService.create(fileExportTask);
        this.exportSignUpUsers(query, f, re, activityId);
        return "";
    }

    @Override
    public String exportOrgUsers(String userId, String activityId, HttpServletResponse response) {
        log.info(":>>> 开始导出承办单位数据:{}", userId);
        Query query = new Query().addCriteria(Criteria.where("invitedByUserId").is(userId).and("activityId").is(activityId));
        List<UserInviteRecord> records = mongoTemplate.find(query, UserInviteRecord.class);
        if (CollectionUtils.isEmpty(records)) {
            log.error(":>>> 活动:{} 用户邀请记录为空:{}", activityId, userId);
            return "";
        }
        HSSFWorkbook workbook = new HSSFWorkbook();
        try {
            OutputStream os = response.getOutputStream();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateStr = sdf.format(new Date());
            String fileName = "邀请记录-" + "-" + dateStr;
            this.setResponseHeader(response, fileName);
            int rowNum = 1;
            int sheetNum = 1;
            //创建一个Excel表单,参数为sheet的名字
            HSSFSheet sheet = workbook.createSheet("sheet" + "-" + sheetNum);
            setActivityUserInviteExcelTitle(workbook, sheet);
            //创建表头
            Integer counter = 0;
            for (UserInviteRecord content : records) {

                log.info(":>>> 导出行数:{}", counter);
                if (counter != 0 && counter % 60000 == 0) {
                    //超过60000就自动创建一个sheet
                    sheetNum++;
                    sheet = workbook.createSheet("sheet-" + sheetNum);
                    setActivityUserInviteExcelTitle(workbook, sheet);
                    //创建表头
                    //新增数据行，并且设置单元格数据
                    rowNum = 1;
                    sheetNum++;
                    log.info(":>>> 操作60000行,创建新sheet");
                }
                HSSFRow row = sheet.createRow(rowNum);
                Query queryUp = new Query().addCriteria(Criteria.where("userId").is(content.getInvitedToUserId()).and("activityId").is(activityId));
                UserParticipateActivityInfo up = mongoTemplate.findOne(queryUp, UserParticipateActivityInfo.class);
                if (Objects.nonNull(up)) {
                    if (Objects.nonNull(up.getName())) {
                        row.createCell(0).setCellValue(up.getName());
                    }
                    //
                    if (StringUtils.isNotBlank(up.getMobile())) {
                        row.createCell(1).setCellValue(up.getMobile());
                    }
                    if (Objects.nonNull(up.getSignUpTime())) {
                        String dateNowStr = TimeUtils.parse(up.getSignUpTime(), "yyyy-MM-dd HH:mm:ss");
                        row.createCell(2).setCellValue(dateNowStr);
                    }
                    if (StringUtils.isNotBlank(up.getUniversityId())) {
                        Query queryUni = new Query().addCriteria(Criteria.where("id").is(up.getUniversityId()));
                        UniversityInfo universityInfo = mongoTemplate.findOne(queryUni, UniversityInfo.class);
                        if (Objects.nonNull(universityInfo) && StringUtils.isNotBlank(universityInfo.getName())) {
                            row.createCell(3).setCellValue(universityInfo.getName());
                        }
                    }
                    if (Objects.nonNull(up.getQaScore())) {
                        row.createCell(4).setCellValue(up.getQaScore());
                    }
                    if (Objects.nonNull(up.getPassed())) {
                        if (Boolean.TRUE.equals(up.getPassed())) {
                            row.createCell(5).setCellValue("通过");
                        } else {
                            row.createCell(5).setCellValue("未通过");
                        }

                    }
                }
                rowNum++;
                counter++;
            }
            //将excel写入到输出流中
            log.info(":>>> flush:{} 行", rowNum);
            workbook.write(os);
            os.flush();
            os.close();
            log.info(":>>> 用户邀请记录内容导出,关闭文件流");
            return "OK";
        } catch (Exception e) {
            log.error(":>>> 用户邀请记录内容导出错误:{}", e);
        }
        return null;
    }

    @Override
    public boolean orderAllUsers(HttpServletResponse response) {
        log.info(":>>> 开始导出所有用户");

        int counter = 0;
        HSSFWorkbook workbook = new HSSFWorkbook();
        HashMap<String, UniversityInfo> universityInfoHashMap = new HashMap<>();
        try {
            OutputStream os = response.getOutputStream();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateStr = sdf.format(new Date());
            String fileName = "用户数据-" + "-" + dateStr;
            this.setResponseHeader(response, fileName);
            int rowNum = 1;
            int sheetNum = 1;
            //创建一个Excel表单,参数为sheet的名字
            HSSFSheet sheet = workbook.createSheet("sheet" + "-" + sheetNum);
            setAllUserExcelTitle(workbook, sheet);
            //创建表头
            Query query = new Query();
            Long total = mongoTemplate.count(query, WechatH5UserPO.class);
            log.info(":>>>  总数量:{}", total);
            Integer pages = total.intValue() / 10000 + 1;
            for (int i = 0; i < pages; i++) {
                log.info(":>>> 开始处理第:{} 页面", i);
                query.limit(10000);
                query.skip(i * 10000);
                List<WechatH5UserPO> userPOS = mongoTemplate.find(query, WechatH5UserPO.class);
                for (WechatH5UserPO content : userPOS) {
                    UniversityInfo universityInfo = null;
                    if (StringUtils.isNotBlank(content.getUniversityId())) {
                        if (universityInfoHashMap.containsKey(content.getUniversityId())) {
                            universityInfo = universityInfoHashMap.get(content.getUniversityId());
                        } else {
                            Query query1 = new Query().addCriteria(Criteria.where("id").is(content.getUniversityId()));
                            universityInfo = mongoTemplate.findOne(query1, UniversityInfo.class);
                            universityInfoHashMap.put(content.getUniversityId(), universityInfo);
                        }
                    } else {
                        if (StringUtils.isNotBlank(content.getAccountInfoId())) {
                            Query query1 = new Query().addCriteria(Criteria.where("userId").is(content.getAccountInfoId()));
                            UserParticipateActivityInfo up = mongoTemplate.findOne(query1, UserParticipateActivityInfo.class);
                            if (Objects.nonNull(up) && StringUtils.isNotBlank(up.getUniversityId())) {
                                Query query2 = new Query().addCriteria(Criteria.where("id").is(up.getUniversityId()));
                                universityInfo = mongoTemplate.findOne(query2, UniversityInfo.class);
                                universityInfoHashMap.put(content.getUniversityId(), universityInfo);
                            }
                        }

                    }
                    log.info(":>>> 导出行数:{}", counter);
                    if (counter != 0 && counter % 60000 == 0) {
                        //超过60000就自动创建一个sheet
                        sheetNum++;
                        sheet = workbook.createSheet("sheet-" + sheetNum);
                        setAllUserExcelTitle(workbook, sheet);
                        //创建表头
                        //新增数据行，并且设置单元格数据
                        rowNum = 1;
                        sheetNum++;
                        log.info(":>>> 操作60000行,创建新sheet");
                    }
                    HSSFRow row = sheet.createRow(rowNum);
                    if (Objects.nonNull(universityInfo)) {
                        row.createCell(2).setCellValue(universityInfo.getName());
                    }
                    //
                    if (StringUtils.isNotBlank(content.getNickName())) {
                        row.createCell(0).setCellValue(content.getNickName());
                    }
                    if (StringUtils.isNotBlank(content.getGender())) {
                        row.createCell(1).setCellValue(content.getGender());
                    }
                    if (Objects.nonNull(content.getProvince())) {
                        row.createCell(3).setCellValue(content.getProvince());
                    }
                    Query query1 = new Query();
                    query1.addCriteria(Criteria.where("userId").is(content.getAccountInfoId()).and("joined").is(Boolean.TRUE));
                    Long c = mongoTemplate.count(query1, UserParticipateActivityInfo.class);
                    row.createCell(4).setCellValue(c);
                    if (Objects.nonNull(content.getGender())) {
                        row.createCell(5).setCellValue(content.getGender());
                    }
                    rowNum++;
                    counter++;
                }
            }
            //将excel写入到输出流中
            log.info(":>>> flush:{} 行", rowNum);
            OutputStream outputStream = new FileOutputStream("./excel-user.xlsx");
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            workbook.write(os);
            os.flush();
            os.close();
            log.info(":>>> 用户内容导出,关闭文件流");
            return true;
        } catch (Exception e) {
            log.error(":>>> 用户内容导出错误:{}", e);
        }
        return false;
    }

    @Override
    public UserCaQueryDomain queryCa(String mobile, String activityId, String taskBizType) {
        log.info(":>>> 开始查询证书:{}", mobile);
        if (StringUtils.isBlank(mobile)) {
            log.error(":>>> 手机号为空");
            throw new BusinessException("手机号为空");
        }
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 活动ID为空");
            activityId = "606ffa6bfb8ede29c8058639";
        }
        Query query = new Query().addCriteria(Criteria.where("mobile").is(mobile).and("activityId").is(activityId));
        ActivityUserRecord record = mongoTemplate.findOne(query, ActivityUserRecord.class);
        if (Objects.isNull(record)) {
            log.info(":>>> 用户:{},未参加活动:{}", mobile, activityId);
            throw new BusinessException("很抱歉,您未参加该次活动,请关注微信公众号:国青实践,参加官方后续活动");
        }
        UserCaQueryDomain domain = new UserCaQueryDomain();
        domain.setName(record.getName());
        domain.setMobile(mobile);
        domain.setUniversityName(record.getUniversityName());
        TaskBizType taskBizTypeEnum = TaskBizType.valueOf(taskBizType);
        Query q = new Query();
        if (taskBizTypeEnum.equals(TaskBizType.INVITE)) {
            if (StringUtils.isNotBlank(record.getCaLevel())) {
                log.info(":>>> 证书等级:{}", record.getCaLevel());
                q.addCriteria(Criteria.where("activityId").is(activityId).and("level").is(record.getCaLevel()));
            }
        }
        if (taskBizTypeEnum.equals(TaskBizType.QA)) {
            if (StringUtils.isNotBlank(record.getCaLevel())) {
                log.info(":>>> 证书等级:{}", record.getCaLevel());
                q.addCriteria(Criteria.where("activityId").is(activityId).and("level").is(record.getCaLevel()));
            }
        }
        CaInfo caInfo = mongoTemplate.findOne(q, CaInfo.class);
        if (Objects.nonNull(caInfo)) {
            domain.setCaName(caInfo.getGroupName());
//                domain.setCaImageUr(caInfo.getGroupImageUrl());
//                domain.setCaDetail(caInfo.getGroupDetail());
        }

        return domain;
    }

    @Override
    public boolean shareBinding(ShareBindingDomain req) {
        log.info(":>>> 开始处理活动分享绑定:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getFromOpenId()) || StringUtils.isBlank(req.getUserId())) {
            log.error(":>>> 活动分享绑定错误:参数错误");
            throw new BusinessException("活动分享绑定错误:参数错误");
        }
        UserPO invitedByUser = visitorUserService.getUserByOpenId(req.getFromOpenId());

        UserPO user = visitorUserService.getUser(req.getUserId());
        ActivityTaskInfo taskInfo = this.findActivityTaskInfo(req.getActivityId(), TaskBizType.INVITE);
        UserInviteCreateVO createVO = new UserInviteCreateVO();
        if (Objects.nonNull(taskInfo)) {

            createVO.setTaskId(taskInfo.getId());
        }
        createVO.setTaskBizType(TaskBizType.INVITE);
        createVO.setInviteTime(new Date());
        createVO.setActivityId(req.getActivityId());
        createVO.setInvitedByUserInfo(invitedByUser);
        createVO.setTargetOpenId(user.getOpenId());
        createVO.setQa(false);
        createVO.setTargetUser(user);
        this.createActivityInvite(createVO);
        return true;
    }

    @Override
    public Page<ActivityFeedInfo> getTaskFeeds(ActivityFeedQueryVO req) {
        log.info(":>>> 开始获取活动Feed流:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId())) {
            log.error(":>>> 获取活动任务Feed流错误:活动ID或任务ID为空");
            throw new BusinessException("获取活动任务Feed流错误:活动ID或任务ID为空");
        }
        if (Objects.isNull(req.getActivityStatus())) {
            req.setActivityStatus(2);
        }
        List<ActivityFeedInfo> infos1 = activityFeedInfoService.getFeedInfo(req.getActivityId(), req.getActivityStatus(), req.getPage() - 1);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        if (CollectionUtils.isEmpty(infos1)) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
        long count = 100;
        return PageableExecutionUtils.getPage(infos1, pageRequest, () -> count);
    }


    /**
     * 更新用户周榜单
     *
     * @param userPO
     * @param taskInfo
     * @param optType,0:累加,1:替换
     */
    @Async
    @Override
    public void updateUserTaskWeekRanking(final UserPO userPO, UserParticipateActivityTaskInfo taskInfo, final Integer optType) {
        log.info(":>>> 开始更新用户周榜单用户:{},任务数据:{},操作类型:{}", JSON.toJSONString(userPO), JSON.toJSONString(taskInfo), optType);
        if (Objects.isNull(userPO) || Objects.isNull(taskInfo) || Objects.isNull(optType)) {
            log.error(":>>> 更新用户周排行榜参数错误:用户、任务量、操作类型为空");
            return;
        }
        Date date = new Date();
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userPO.getId()).and("taskId").is(taskInfo.getTaskId()).and("activityId").is(taskInfo.getActivityId()).and("taskBizType").is(taskInfo.getBizType()));

        Date startWeekTime = TimeUtils.getBeginDayOfWeek();
        Date endWeekTime = TimeUtils.getEndDayOfWeek();
        Criteria criteria = new Criteria().andOperator(Criteria.where("weekTime").gte(TimeUtils.dateToISODate(startWeekTime)), Criteria.where("weekTime").lte(TimeUtils.dateToISODate(endWeekTime)));
        query.addCriteria(criteria);
        UserWeekActivityTaskRanking ranking = mongoTemplate.findOne(query, UserWeekActivityTaskRanking.class);
        if (Objects.isNull(ranking)) {
            ranking = new UserWeekActivityTaskRanking();
            ranking.setActivityId(taskInfo.getActivityId());
            ranking.setUserId(userPO.getId());
            ranking.setTaskId(taskInfo.getTaskId());
            ranking.setTaskBizType(taskInfo.getBizType());
            ranking.setCreatedTime(date);
            ranking.setProvince(userPO.getProvince());
            ranking.setUniversityName(userPO.getUniversityName());
            ranking.setImageUrl(userPO.getAvatarUrl());
            ranking.setName(userPO.getNickName());
            ranking.setQuantity(taskInfo.getQuantity());
            // 时间设置为每周的第一天
            ranking.setWeekTime(startWeekTime);
            mongoTemplate.insert(ranking);
            return;
        }
        Query queryUpdate = new Query().addCriteria(Criteria.where("id").is(ranking.getId()));
        Update update = new Update();
        switch (optType) {
            // 累加
            case 0:
                update.inc("quantity", taskInfo.getQuantity());
                break;
            // 替换
            case 1:
                update.set("quantity", taskInfo.getQuantity());
                break;
            default:
                break;
        }
        update.set("updatedTime", date);
        UpdateResult result = mongoTemplate.updateFirst(queryUpdate, update, UserWeekActivityTaskRanking.class);
        log.info(":>>> 更新用户:{},任务周榜单:{},结果数量为:{}", userPO.getId(), ranking.getId(), result.getModifiedCount());
    }

    @Override
    public HashMap<String, Object> importUserCa(MultipartFile file, String activityId) {
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 活动:{} 为空", activityId);
            throw new BusinessException("批次号为空");
        }
        Query query1 = new Query().addCriteria(Criteria.where("id").is(activityId));
        ActivityInfo info = mongoTemplate.findOne(query1, ActivityInfo.class);
        if (Objects.isNull(info)) {
            log.error(":>>> 活动不存在:{}", activityId);
            throw new BusinessException("活动不存在");
        }
        HashMap<String, Object> result = new HashMap<>();
        Date date = new Date();
        log.info(":>>> 开始导入奖励领取数据:{}");
        try {
            InputStream is = file.getInputStream();
            String fileName = file.getName();
//            if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
//                log.error(":>>> 批量导入Excel格式错误:{}", fileName);
//                throw new BusinessException("导入文件格式错误");
//            }
            boolean isExcel2003 = false;
            if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
                isExcel2003 = false;
            }
            Date now = new Date();
            Workbook wb = null;
            if (isExcel2003) {
                wb = new HSSFWorkbook(is);
            } else {
                wb = new XSSFWorkbook(is);
            }
            Sheet sheet = wb.getSheetAt(0);
            List<HashMap<String, Object>> errors = new ArrayList<>();
            log.info(":>>> 表格的行数:{}", sheet.getLastRowNum());
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                HashMap<String, Object> errorMsg = new HashMap<>();
                log.info(":>>> 处理第:{} 行", i);
                Row row = sheet.getRow(i);
                if (Objects.isNull(row)) {
                    log.info(":>>> 处理第:{} 行为空跳出循环", i);
                    break;
                }
                Cell cell0 = row.getCell(0);
                Cell cell1 = row.getCell(1);
                Cell cell2 = row.getCell(2);
                Cell cell3 = row.getCell(3);
                Cell cell4 = row.getCell(4);
                if (Objects.isNull(cell0) || Objects.isNull(cell1) || Objects.isNull(cell2) || Objects.isNull(cell3) || Objects.isNull(cell4)) {
                    errorMsg.put("row", i + 1);
                    errorMsg.put("colum", 1);
                    errorMsg.put("message", "导入数据为空");
                    errors.add(errorMsg);
                    log.error(":>>> 第:{} 行格式错误,导入数据为空", i + 1);
                    continue;
                }
                String name = getCellStr(cell0);
                String un = getCellStr(cell1);
                String mobile = getCellStr(cell2);
                String q = getCellStr(cell3);
                String level = getCellStr(cell4);
                log.info(":>>> 姓名:{},大学:{},电话:{},q:{},level:{}", name, un, mobile, q, level);
                try {
                    if (StringUtils.isBlank(name)) {
                        errorMsg.put("row", i + 1);
                        errorMsg.put("colum", 1);
                        errorMsg.put("message", "行格式错误,名字为空");
                        errors.add(errorMsg);
                        log.error(":>>> 第:{} 行格式错误,名字为空", i + 1);
                    }
                    if (StringUtils.isBlank(un)) {
                        errorMsg.put("row", i + 1);
                        errorMsg.put("colum", 1);
                        errorMsg.put("message", "大学为空");
                        errors.add(errorMsg);
                        log.error(":>>> 第:{} 行格式错误,物流公司为空", i + 1);
                    }
                    if (StringUtils.isBlank(mobile)) {
                        errorMsg.put("row", i + 1);
                        errorMsg.put("colum", 1);
                        errorMsg.put("message", "电话为空");
                        errors.add(errorMsg);
                        log.error(":>>> 第:{} 行格式错误,物流编号为空", i + 1);
                    }
//                    if (StringUtils.isBlank(q)) {
//                        errorMsg.put("row", i + 1);
//                        errorMsg.put("colum", 1);
//                        errorMsg.put("message", " 分享值为空");
//                        errors.add(errorMsg);
//                        log.error(":>>> 第:{} 行格式错误,物流编号为空", i + 1);
//                    }
                    if (StringUtils.isBlank(level)) {
                        errorMsg.put("row", i + 1);
                        errorMsg.put("colum", 1);
                        errorMsg.put("message", "等级为空");
                        errors.add(errorMsg);
                        log.error(":>>> 第:{} 行格式错误,物流编号为空", i + 1);
                    }
                    Query query2 = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("mobile").is(mobile));
                    boolean exist = mongoTemplate.exists(query2, ActivityUserRecord.class);
                    if (!exist) {
                        ActivityUserRecord userCaInfo = new ActivityUserRecord();
                        userCaInfo.setActivityId(activityId);
                        //  userCaInfo.setCaLevel(level);
                        userCaInfo.setMobile(mobile);
                        userCaInfo.setName(name);
                        if (StringUtils.isNotBlank(q)) {
                            userCaInfo.setQ(Integer.valueOf(q));
                        }
                        userCaInfo.setUniversityName(un);
                        userCaInfo.setCreatedTime(new Date());
                        mongoTemplate.insert(userCaInfo);
                    }
                } catch (Exception e) {
                    log.error(":>>> 第:{} 行格式错误", e);
                    errorMsg.put("row", i + 1);
                    errorMsg.put("colum", 1);
                    errorMsg.put("message", "手机号或销量格式错误,订单标示为空");
                    errors.add(errorMsg);
                    continue;
                }
            }
            if (!errors.isEmpty()) {
                log.error(":>>> 导入包含:{} 条错误信息", errors.size());
                result.put("error", errors);
                result.put("hasError", true);
                return result;
            }
            result.put("hasError", false);
            return result;
        } catch (Exception e) {
            log.error(":>>> 导入销量数据错误:{}", e);

        }
        return result;
    }

    @Override
    public ActivityInfo getOffLineDetail(String activityId) {
        log.info(":>>> 开始获取线下活动详情:{}", activityId);
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 开始获取线下活动详情参数错误:活动ID为空", activityId);
            throw new BusinessException("获取线下活动详情参数错误");
        }
        ActivityInfo activityInfo = this.findOne(activityId);
        return activityInfo;
    }

    @Override
    public ActivityTaskInfo getTaskInfo(String activityId, TaskBizType taskBizType) {
        log.info(":>>> 开始获取任务详情:{},{}", activityId, taskBizType);
        if (StringUtils.isBlank(activityId) || Objects.isNull(taskBizType)) {
            log.error(":>>> 获取任务详情参数错误:活动ID或任务业务为空");
            throw new BusinessException("获取任务详情参数错误");
        }
        ActivityTaskInfo taskInfo = this.findActivityTaskInfo(activityId, taskBizType);
        log.info(":>>> 任务详情为:{}", JSON.toJSONString(taskInfo));
        if (Objects.isNull(taskInfo)) {
            return taskInfo;
        }
        return taskInfo;
    }

    @Override
    public List<ActivityTaskInfo> getTaskList(String activityId) {
        log.info(":>>> 开始获取任务详情:{},{}", activityId);
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 获取任务详情参数错误:活动ID或任务业务为空");
            throw new BusinessException("获取任务详情参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("opened").is(Boolean.TRUE).and("deleted").is(Boolean.FALSE));
        List<ActivityTaskInfo> activityTaskInfos = mongoTemplate.find(query, ActivityTaskInfo.class);
        return activityTaskInfos;
    }

    @Override
    public PlayBillDomain getPlayBill(UserPO userPO, String taskId, String appId, String platform, String authMode) {
        log.info(":>>> 开始获取分享海报 taskId:{},userPO:{}", taskId, JSON.toJSONString(userPO));
        if (StringUtils.isBlank(taskId) || Objects.isNull(userPO)) {
            log.error(":>>>  获取分享海报参数错误");
            throw new BusinessException("获取分享海报参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(taskId));
        ActivityTaskInfo taskInfo = mongoTemplate.findOne(query, ActivityTaskInfo.class);
        if (Objects.isNull(taskId)) {
            log.error(":>>>  获取分享海报参数错误:任务不存在");
            throw new BusinessException("获取分享海报参数错误:任务不存在");
        }
        ActivityInfo activityInfo = this.findOne(taskInfo.getActivityId());
        PlayBillDomain res = taskInfo.getPlayBill();
        if (Objects.isNull(res)) {
            log.error(":>>> 任务海报信息配置错误:{}", taskId);
            throw new BusinessException("任务海报信息配置错误");
        }
        switch (taskInfo.getTaskBizType()) {
            case ORGANIZER:
                ActivityOrganizerInfo organizerInfo = activityOrganizerInfoService.find(taskInfo.getActivityId(), userPO.getId());
                if (Objects.nonNull(organizerInfo)) {
                    res.setType(1);
                    res.setOrgName(organizerInfo.getOrgName());
                }
                // 设置大学信息
                UniversityInfo universityInfo = universityService.get(userPO);
                if (Objects.nonNull(universityInfo)) {
                    res.setUniversityName(universityInfo.getName());
                    log.info(":>>> 海报大学名字:{}", universityInfo.getName());
                    res.setOrgName(universityInfo.getName() + ":" + organizerInfo.getOrgName());
                }
                break;
        }
        res.setNickName(userPO.getNickName());
        if (Objects.nonNull(userPO) && StringUtils.isBlank(userPO.getAvatarUrl())) {
            userPO.setAvatarUrl(defaultHeadUrl);
        }
        res.setAvatarUrl(userPO.getAvatarUrl());
        if (Objects.nonNull(activityInfo)) {
            res.setTitle(activityInfo.getShareName());
            res.setImgUrl(activityInfo.getShareImageUrl());
            res.setDesc(activityInfo.getShareOName());
        }
        // 英语竞赛
        if (activityGroupService.findByActivityId(taskInfo.getActivityId())) {
            final String catalogue = platformConfigService.getContestCatalogue();
            String qrCode = "%s" + catalogue + "index.html?a=a#/pages/home?activityId=" + taskInfo.getActivityId() + "&taskId=" + taskId + "&appId=" + appId + "&sharedByOpenId=" + userPO.getOpenId() + "&theme=" + activityInfo.getThemeColor() + "&sharedByUserId=" + userPO.getId() + "&sPlatform" + "=" + platform;
            qrCode = this.setAuthModeForQrCode(qrCode, authMode);

            log.info(":>>> 英语竞赛类:>>> 用户的海报信息:{}", JSON.toJSONString(res));
            String shortUrl = ShotUrlUtil.shortUrl(qrCode);
            if (!huoLinkerInfoService.exist(shortUrl)) {
                HuoLinkerInfo huoLinkerInfo = new HuoLinkerInfo();
                huoLinkerInfo.setActivityId(activityInfo.getId());
                huoLinkerInfo.setBizType("C");
                huoLinkerInfo.setDomain(platformConfigService.getContestBizFrontDomain());
                huoLinkerInfo.setCreatedTime(new Date());
                huoLinkerInfo.setUrl(qrCode);
                huoLinkerInfo.setKey(shortUrl);
                huoLinkerInfo.setUserId(userPO.getId());
                huoLinkerInfo.setCatalogue(catalogue);
                huoLinkerInfo.setVersion("V2");
                huoLinkerInfoService.create(huoLinkerInfo);
                res.setLink(qrCode);
                res.setQrCode(platformConfigService.getShortUrlDomain() + "/" + shortUrl);
            }
            return res;
        }
        String catalogue = "";
        String qrCode = "";
        if ("contest-plus".equals(activityInfo.getType())) {
            catalogue = platformConfigService.getContestPlusCatalogue();
            qrCode = "%s" + catalogue + "#/pages/home?activityId=" + taskInfo.getActivityId() + "&taskId=" + taskId + "&appId=" + appId + "&sharedByOpenId=" + userPO.getOpenId() + "&theme=" + activityInfo.getThemeColor() + "&sharedByUserId=" + userPO.getId() + "&sPlatform" + "=" + platform;
            qrCode = this.setAuthModeForQrCode(qrCode, authMode);
        } else if ("vote".equals(activityInfo.getType())) {
            catalogue = platformConfigService.getVoteCatalogue();
            qrCode = "%s" + catalogue + "index.html#/pages/activity-detial?activityId=" + taskInfo.getActivityId() + "&taskId=" + taskId + "&appId=" + appId + "&sharedByOpenId=" + userPO.getOpenId() + "&theme=" + activityInfo.getThemeColor() + "&sharedByUserId=" + userPO.getId() + "&sPlatform" + "=" + platform;
            qrCode = this.setAuthModeForQrCode(qrCode, authMode);
        } else {
            catalogue = platformConfigService.getCatalogue();
            qrCode = "%s" + catalogue + "index.html#/pages/activity-detial?activityId=" + taskInfo.getActivityId() + "&taskId=" + taskId + "&appId=" + appId + "&sharedByOpenId=" + userPO.getOpenId() + "&theme=" + activityInfo.getThemeColor() + "&sharedByUserId=" + userPO.getId() + "&sPlatform" + "=" + platform;
            qrCode = this.setAuthModeForQrCode(qrCode, authMode);
        }
        if (platform.equals("qq-h5")) {
            log.info(":>>> 平台是qq-h5");
            qrCode = qrCode + "&authorizeMode=qq";
        }
        String shortUrl = ShotUrlUtil.shortUrl(qrCode);
        if (!huoLinkerInfoService.exist(shortUrl)) {
            HuoLinkerInfo huoLinkerInfo = new HuoLinkerInfo();
            huoLinkerInfo.setActivityId(activityInfo.getId());
            huoLinkerInfo.setBizType("H");
            huoLinkerInfo.setDomain(platformConfigService.getBizFrontDomain());
            huoLinkerInfo.setCreatedTime(new Date());
            huoLinkerInfo.setUrl(qrCode);
            huoLinkerInfo.setKey(shortUrl);
            huoLinkerInfo.setUserId(userPO.getId());
            huoLinkerInfo.setCatalogue(catalogue);
            huoLinkerInfo.setPlatform(platform);
            huoLinkerInfo.setActivityType(activityInfo.getType());
            huoLinkerInfo.setVersion("V2");
            huoLinkerInfoService.create(huoLinkerInfo);
        }
        String qrCode1 = "";
        switch (platform) {
            case "qq":
                String url = "/pages/tabbar/tabbar?activityId=" + taskInfo.getActivityId() + "&taskId=" + taskId + "&appId=" + appId + "&sharedByOpenId=" + userPO.getOpenId();
                String u = "https://m.q.qq.com/a/p/%s?s=%s";
                qrCode1 = String.format(u, appId, URLUtils.getURLEncoderString(url));
                break;
            case "wechat-h5":
                qrCode1 = platformConfigService.getShortUrlDomain() + "/" + shortUrl;
                break;
            default:
                break;
        }
        res.setQrCode(qrCode1);
        res.setLink(qrCode1);
        if (platform.equals("qq-h5") && StringUtils.isNotBlank(res.getPlayBillImageUrlQQH5())) {
            res.setPlayBillImageUrl(res.getPlayBillImageUrlQQH5());
        }
        log.info(":>>> 用户的海报信息:{}", JSON.toJSONString(res));
        return res;
    }

    @Override
    public boolean reeData(String activityId, UserPO userPO) {
        log.info(":>>> 开始补偿数据:{}", activityId);
        Query queryTask = new Query().addCriteria(Criteria.where("taskBizType").is(TaskBizType.INVITE).and("activityId").is(activityId));
        ActivityTaskInfo taskInfo = mongoTemplate.findOne(queryTask, ActivityTaskInfo.class);
        if (Objects.isNull(taskInfo)) {
            log.error(":>>> 无配置的任务,请联系客服");
            throw new BusinessException("无配置的任务,请联系客服");
        }
        this.reeQa(activityId, taskInfo.getId(), userPO);
        Long count = userActivityTaskRankingService.countByActivityIdAndTaskId(activityId, taskInfo.getId());

        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("taskId").is(taskInfo.getId()));
        log.info(":>>> 活动ID:{},任务ID:{}", activityId, taskInfo.getId());
        // 设置省查询
        Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
        query.with(sort);
        Integer pageSize = 10;
        for (int i = 0; i < count.intValue() / pageSize + 1; i++) {
            log.info(":>>> 开始处理低:{} 页,数量为:{}");
            PageRequest pageRequest = PageRequest.of(i, pageSize);
            query.with(pageRequest);
            List<UserActivityTaskRanking> rankings = userActivityTaskRankingService.find(query);
            log.info(":>>> 开始处理第:{} 页,数量为:{}", i, rankings == null ? 0 : rankings.size());
            if (!CollectionUtils.isEmpty(rankings)) {
                for (UserActivityTaskRanking u : rankings) {
                    log.info(":>>> 开始处理用户:{},任务量:{}", u.getUserId(), u.getQuantity());
                    Double points = 0.0D;
                    Query queryInvite = new Query();
                    queryInvite.addCriteria(Criteria.where("invitedByUserId").is(u.getUserId()));
                    queryInvite.addCriteria(Criteria.where("activityId").is(activityId));
                    queryInvite.addCriteria(Criteria.where("taskId").is(taskInfo.getId()));
                    queryInvite.addCriteria(Criteria.where("joinStatus").is(Boolean.TRUE));
                    Long inviteCount = mongoTemplate.count(queryInvite, UserInviteRecord.class);
                    points = points + inviteCount.intValue();
                    log.info(":>>> 用户:{} 邀请数量:{}", u.getUserId(), inviteCount);
                    // 线下志愿活动
                    ActivityFootPrintDomain printDomain = getActivityFootPrint(u.getUserId(), activityId, TaskBizType.OFF_LINE.name());
                    log.info(":>>> 活动有线下活动:{},状态:{},{} ", activityId, u.getUserId(), JSON.toJSONString(printDomain));
                    /**
                     * 线下组织活动状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
                     */
                    ActivityTaskRule taskRule = activityTaskRuleService.find(activityId, TaskBizType.OFF_LINE.name());
                    if (Objects.nonNull(taskRule)) {
                        if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                            points = points + taskRule.getPoints();
                            log.info(":>>> 用户:{} 线下志愿者活动审核通过累计,加分:{}", u.getUserId(), taskRule.getPoints());
                            // 审核通过
                        }
                    }
                    // 直播
                    ActivityFootPrintDomain printDomainB = getActivityFootPrint(u.getUserId(), activityId, TaskBizType.BROADCASAT.name());
                    log.info(":>>> 直播活动:{},状态:{},{} ", activityId, u.getUserId(), JSON.toJSONString(printDomainB));

                    ActivityTaskRule taskRuleB = activityTaskRuleService.find(activityId, TaskBizType.BROADCASAT.name());
                    if (Objects.nonNull(taskRuleB)) {
                        if (printDomainB.getPassedNum().compareTo(taskRuleB.getThreshold()) != -1) {
                            points = points + taskRuleB.getPoints();
                            log.info(":>>> 用户:{} 直播活动审核通过累计,加分:{}", u.getUserId(), taskRuleB.getPoints());
                            // 审核通过
                        }
                    }
                    // 福利
                    ActivityFootPrintDomain printDomainF = getActivityFootPrint(u.getUserId(), activityId, TaskBizType.WELFARE.name());
                    log.info(":>>> 活动福利:{},状态:{},{} ", activityId, u.getUserId(), JSON.toJSONString(printDomainF));

                    ActivityTaskRule taskRuleF = activityTaskRuleService.find(activityId, TaskBizType.WELFARE.name());
                    if (Objects.nonNull(taskRuleF)) {
                        if (printDomainF.getPassedNum().compareTo(taskRuleF.getThreshold()) != -1) {
                            points = points + taskRuleF.getPoints();
                            log.info(":>>> 用户:{} 活动福利审核通过累计,加分:{}", u.getUserId(), taskRuleF.getPoints());
                            // 审核通过
                        }
                    }

                    if (points.intValue() == u.getQuantity().intValue()) {
                        log.info(":>>> 用户值相等,不需要累计", u.getUserId());
                    } else {
                        if (points.intValue() > u.getQuantity().intValue()) {
                            log.info(":>>> 用户:{} 值不相等,需要更新:{} --->:{}", u.getUserId(), u.getQuantity(), points);
                            UserActivityTaskRanking update = new UserActivityTaskRanking();
                            update.setId(u.getId());
                            update.setQuantity(points);
                            update.setQuantityBack(u.getQuantity().intValue());
                            userActivityTaskRankingService.updateById(update);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public ReceiveCaVO receiveCa(String activityId, String appId, UserPO userPO) {
        log.info(":>>> 开始领取证书 activityId:{},userId:{},appId: {}", activityId, userPO.getId() == null ? null : userPO.getId());
        if (StringUtils.isBlank(activityId) || Objects.isNull(userPO)) {
            log.error(":>>> 领取证书参数错误:活动ID或用户为空");
            throw new BusinessException("领取证书参数错误:活动ID或用户为空");
        }
        ReceiveCaVO res = new ReceiveCaVO();
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);

        Boolean otherPlatform = activityInfo.getOtherPlatform();
        res.setRecieveRewardDetail(activityInfo.getRecieveRewardDetail());
        ActivityRecieveRule recieveRule = null;
        ActivityTaskDataDomain d = null;
        if (!otherPlatform) {
            recieveRule = activityRecieveRuleService.findByActivityId(activityId);
            log.info(":>>> 活动:{} 证书领取规则配置:{}", activityId, JSON.toJSONString(recieveRule));
            if (Objects.isNull(recieveRule) || CollectionUtils.isEmpty(recieveRule.getPopularCaNames())) {
                log.error(":>>> 活动证书领取配置错误:{}", activityId);
                throw new BusinessException("活动证书领取配置错误,请联系客服");
            }
            d = this.getActivityTaskDataDomain(activityInfo, userPO.getId());
            d.setHideDetail(recieveRule.getHideDetail());
            String caNameF = this.getCaName(activityInfo, d.getCaName(), d.getContestCaName(), TaskBizType.INVITE, recieveRule);
            caNameF = filterCaName(activityInfo, caNameF, userPO.getId(), recieveRule);
            log.info(":>>> 用户:{} 活动:{} ,任务类型:{} 证书:{}", userPO.getId(), activityId, TaskBizType.INVITE, caNameF);
            d.setCaName(caNameF);
            res.getDatas().put(TaskBizType.INVITE.name(), d);
            List<ActivityCaRule> rules = cacheActivityCaRuleService.findByActivityId(activityId);
            log.info(":>>> 活动:{} 证书规则大小:{}", activityId, rules == null ? 0 : rules.size());
            if (!CollectionUtils.isEmpty(rules)) {
                for (ActivityCaRule rule : rules) {
                    String caName = "";
                    if (!otherPlatform) {
                        caName = this.getCaName(activityInfo, d.getCaName(), d.getContestCaName(), TaskBizType.valueOf(rule.getTaskBizType()), recieveRule);
                        caName = filterCaName(activityInfo, caName, userPO.getId(), recieveRule);
                        log.info(":>>> 用户:{} 活动:{} ,任务类型:{} 证书:{}", userPO.getId(), activityId, rule.getTaskBizType(), caName);
                    } else {
                        caName = "光盘活动证书";
                    }

                    switch (rule.getMaterial()) {
                        // 电子证书
                        case 0: {
                            RecieveCaDetailVO r = new RecieveCaDetailVO();
                            r.setTaskBizeType(rule.getTaskBizType());
                            r.setButtonName(rule.getButtonName());
                            r.setStartTime(rule.getStartTime());
                            r.setEndTime(rule.getEndTime());
                            r.setActivityId(rule.getActivityId());
                            r.setTips(rule.getTips());
                            r.setDesc(activityInfo.getDigitalCaDetail());
                            /**
                             * 0:未领取,1:已经领取,未支付,2:已支付,3:未开始,4:领取结束
                             */
                            if (new Date().before(rule.getStartTime())) {
                                r.setStatus(3);
                            } else if (new Date().after(rule.getEndTime())) {
                                r.setStatus(4);
                            } else {
                                r.setStatus(0);
                            }
                            r.setCaName(caName);
                            r.setDetail(rule.getDetail());
                            res.getDigitCas().put(rule.getTaskBizType(), r);
                        }
                        break;
                        // 纸质证书
                        case 1: {
                            RecieveCaDetailVO r = new RecieveCaDetailVO();
                            r.setTaskBizeType(rule.getTaskBizType());
                            r.setButtonName(rule.getButtonName());
                            r.setStartTime(rule.getStartTime());
                            r.setEndTime(rule.getEndTime());
                            r.setActivityId(rule.getActivityId());
                            r.setTips(rule.getTips());
                            r.setDesc(activityInfo.getDigitalCaDetail());
                            r.setCaName(caName);
                            r.setDetail(rule.getDetail());
                            res.getPaperCas().put(rule.getTaskBizType(), r);
                        }
                        break;
                    }
                }
            }
        }
        return res;
    }

    @Override
    public ReceiveCaVO receiveCa(String activityId, String appId, UserPO userPO, Integer rewardType) {
        log.info(":>>> 开始领取证书 activityId:{},userId:{},appId: {}", activityId, userPO.getId() == null ? null : userPO.getId());
        if (StringUtils.isBlank(activityId) || Objects.isNull(userPO)) {
            log.error(":>>> 领取证书参数错误:活动ID或用户为空");
            throw new BusinessException("领取证书参数错误:活动ID或用户为空");
        }
        // 1:活动,2:收款
//        activityDauDataService.incr(userPO.getId(), activityId, 2);
        Long currentTime = System.currentTimeMillis();
        AtomicBoolean hasOrder = new AtomicBoolean(false);
        ReceiveCaVO res = new ReceiveCaVO();
//        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        ActivityInfo activityInfo = this.findOne(activityId);
        String universityName = "";
        String name = "";
        Boolean joined = Boolean.TRUE;
        try {
            ActivityUserRecord userRecord = cacheActivityUserRecordService.findByActivityIdAndOpenId(activityId, userPO.getOpenId(), null);
            if (Objects.isNull(userRecord)) {
                res.setUrl(platformConfigService.getBizFrontPayDomain() + "/h5/index" + ".html#/pages/activity-reward?activityId=" + activityId + "&appId=" + appId + "&bizType=2");
            } else {
                res.setNickName(userPO.getNickName());
                res.setAvatarUrl(userPO.getAvatarUrl());
                universityName = userRecord.getUniversityName();
                name = userRecord.getName();
            }
        } catch (Exception e) {
            log.error("活动id ->{} appId ->{} openid  ->{}", activityId, appId, userPO.getOpenId(), e);
        }
        res.setRecieveRewardDetail(activityInfo.getRecieveRewardDetail());
        if (Boolean.TRUE.equals(activityInfo.getHasOrganizer())) {
            ActivityOrganizerInfo activityOrganizerInfo = activityOrganizerInfoService.find(activityInfo.getId(), userPO.getId());
            log.info(":>>> 用户组织单位信息:{}", JSON.toJSONString(activityOrganizerInfo));
            //0:待审核,1:审核通过,2:审核不通过，3:未报名
            if (Objects.nonNull(activityOrganizerInfo) && 1 == activityOrganizerInfo.getStatus().intValue()) {
                ActivityTaskDataDomain dOrg = this.getActivityOrgTaskDomain(activityInfo, userPO.getId());
                if (Objects.nonNull(dOrg)) {
                    if (!("无".equals(dOrg.getCaName()) || "暂无证书".equals(dOrg.getCaName()))) {
                        res.getDatas().put(TaskBizType.ORGANIZER.name(), dOrg);
                    }
                }
            }
        }
        res.setOtherPlatform(activityInfo.getOtherPlatform());
        res.setRecieveRewardDetail(activityInfo.getRecieveRewardDetail());
        res.setRecieveCaDetail(activityInfo.getRecieveCaDetail());
        res.setJoined(joined);
        res.setUniversityName(universityName);
        res.setDigitalCaDetail(activityInfo.getDigitalCaDetail());
        res.setCsInfos(activityInfo.getCsInfos());
        res.setIncentivesStartTime(activityInfo.getIncentivesStartTime());
        res.setIncentivesEndTime(activityInfo.getIncentivesEndTime());
        res.setLayoutNo(activityInfo.getLayoutNo());

        PayConfigPage payConfig = activityPayConfigService.findByActivityId(activityId, rewardType);
        CaReceiveConfigRes caReceiveConfig = new CaReceiveConfigRes();
        caReceiveConfig.setReceiveCertificateDesc(payConfig.getReceiveCertificateDesc());
        caReceiveConfig.setCertificateDesc(payConfig.getCertificateDesc());
        caReceiveConfig.setReceiveDesc(payConfig.getReceiveDesc());
        if (1 == rewardType) {
            caReceiveConfig.setAboutDesc(payConfig.getDigitalAboutDesc());
        } else {
            caReceiveConfig.setAboutDesc(payConfig.getAboutDesc());
        }
        caReceiveConfig.setDigitalAboutDesc(payConfig.getDigitalAboutDesc());
        caReceiveConfig.setShowCountDown(payConfig.getShowCountDown());
        caReceiveConfig.setBackgroundThemeColor(payConfig.getBackgroundThemeColor());
        caReceiveConfig.setCountdownColor(payConfig.getCountdownColor());
        caReceiveConfig.setLevelColor(payConfig.getLevelColor());
        List<PayButtonConfigPage> payButtonConfigList = payConfig.getPayButtonConfigList();
        List<CaReceiveButtonConfigRes> receiveButtonConfigList = payButtonConfigList.stream().map(payButtonConfig -> {
            CaReceiveButtonConfigRes caReceiveButtonConfig = new CaReceiveButtonConfigRes();
            caReceiveButtonConfig.setActivityId(activityId);
            caReceiveButtonConfig.setButtonName(payButtonConfig.getButtonPrimaryDesc());
            caReceiveButtonConfig.setTips(payButtonConfig.getButtonSecondaryDesc());
            caReceiveButtonConfig.setTaskBizType(payButtonConfig.getCaType());
            caReceiveButtonConfig.setId(payButtonConfig.getId());
            caReceiveButtonConfig.setUserInfoCertificateShow(payButtonConfig.getUserInfoCertificateShow());
            caReceiveButtonConfig.setPayButtonType(payButtonConfig.getPayButtonType());
            caReceiveButtonConfig.setPayButtonImgUrl(payButtonConfig.getPayButtonImgUrl());
            caReceiveButtonConfig.setButtonColor(payButtonConfig.getButtonColor());
            caReceiveButtonConfig.setLevelShow(payButtonConfig.getLevelShow());
            caReceiveButtonConfig.setPriority(payButtonConfig.getPriority());
            Date now = new Date();
            String buttonType = payButtonConfig.getButtonType();
            caReceiveButtonConfig.setButtonType(buttonType);
            caReceiveButtonConfig.setControlByQ(payButtonConfig.getControlByQ());
            caReceiveButtonConfig.setStartQ(payButtonConfig.getStartQ());
            caReceiveButtonConfig.setEndQ(payButtonConfig.getEndQ());
            switch (buttonType) {
                //纸质证书按钮
                case PayButtonConfigPage.PAPER_CERTIFICATE:
                    caReceiveButtonConfig.setButtonType(PayButtonConfigPage.PAPER_CERTIFICATE);
                    Integer status = getCaRecieveStatus(userPO.getId(), activityId, payButtonConfig.getCaType());
                    //0:未领取,1:已经领取,未支付,2:已支付,3:未开始,4:领取结束
                    if (status.intValue() == 2) {
                        hasOrder.set(true);
                        caReceiveButtonConfig.setStatus(4);
                    } else if (getCaRecieveRefundStatus(userPO.getId(), activityId, payButtonConfig.getCaType())) {
                        hasOrder.set(true);
                        caReceiveButtonConfig.setStatus(1);
                    }
                    if (StringUtils.isNotBlank(payButtonConfig.getReceiveDesc())) {
                        caReceiveButtonConfig.setReceiveDesc(payButtonConfig.getReceiveDesc());
                    } else {
                        caReceiveButtonConfig.setReceiveDesc(payConfig.getReceiveDesc());
                    }
                    caReceiveButtonConfig.setCaType(2);
                    break;
                case PayButtonConfigPage.CA_CERTIFICATE:
                    caReceiveButtonConfig.setButtonType(PayButtonConfigPage.CA_CERTIFICATE);
                    caReceiveButtonConfig.setCaType(1);
                    break;
                case PayButtonConfigPage.POPUP:
                    caReceiveButtonConfig.setButtonType(PayButtonConfigPage.POPUP);
                    caReceiveButtonConfig.setPopupUrl(payButtonConfig.getPopupUrl());
                    if (now.before(payButtonConfig.getStartTime())) {
                        //当前时间小于开始时间，可以弹框
                        caReceiveButtonConfig.setStatus(3);
                    }
                    break;
                case PayButtonConfigPage.GIFT_POPUP:
                    caReceiveButtonConfig.setButtonType(PayButtonConfigPage.GIFT_POPUP);
                    caReceiveButtonConfig.setPopupUrl(payButtonConfig.getPopupUrl());
                    caReceiveButtonConfig.setStartTime(payButtonConfig.getStartTime().getTime());
                    caReceiveButtonConfig.setEndTime(payButtonConfig.getEndTime().getTime());
                    if (now.before(payButtonConfig.getStartTime())) {
                        //当前时间小于开始时间，可以弹框
                        caReceiveButtonConfig.setStatus(3);
                    }
                    break;
                default:
            }
            Date endTime = payButtonConfig.getEndTime();
            Date startTime = payButtonConfig.getStartTime();
            if ((Objects.nonNull(endTime) && endTime.before(now)) || (Objects.nonNull(startTime) && startTime.after(now))) {
                caReceiveButtonConfig.setStatus(3);
            }
            if (!PayButtonConfigPage.POPUP.equals(buttonType) && Objects.nonNull(endTime) && endTime.before(now)) {
                caReceiveButtonConfig.setButtonName("领取已结束！");
            }
            return caReceiveButtonConfig;
        }).collect(Collectors.toList());
        if (rewardType == 0) {
            List<CaReceiveButtonConfigRes> result = new ArrayList<>();
            Set<String> taskBizTypeSet = cacheActivityUserRecordService.findBizTypeByActivityIdAndOpenId(activityId, userPO.getOpenId());
            receiveButtonConfigList.stream().forEach(receiveButtonConfig -> {
                if (taskBizTypeSet.contains(receiveButtonConfig.getTaskBizType())) {
                    result.add(receiveButtonConfig);
                }
                if (PayButtonConfigPage.POPUP.equals(receiveButtonConfig.getButtonType())) {
                    result.add(receiveButtonConfig);
                }
                if (PayButtonConfigPage.GIFT_POPUP.equals(receiveButtonConfig.getButtonType())) {
                    result.add(receiveButtonConfig);
                }
            });
            if (CollectionUtils.isEmpty(taskBizTypeSet)) {
                caReceiveConfig.setCaReceiveButtonConfigList(receiveButtonConfigList.stream().sorted(Comparator.comparing(CaReceiveButtonConfigRes::getPriority).reversed()).collect(Collectors.toList()));
            } else {
                caReceiveConfig.setCaReceiveButtonConfigList(result.stream().sorted(Comparator.comparing(CaReceiveButtonConfigRes::getPriority).reversed()).collect(Collectors.toList()));
            }
        } else {
            caReceiveConfig.setCaReceiveButtonConfigList(receiveButtonConfigList.stream().sorted(Comparator.comparing(CaReceiveButtonConfigRes::getPriority).reversed()).collect(Collectors.toList()));
        }
        caReceiveConfig.setLayer(payConfig.getLayer());
        caReceiveConfig.setLayerUrl(payConfig.getLayerUrl());
        res.setCaReceiveConfig(caReceiveConfig);
        //res.setUserInfoCertificateShow(payConfig.getUserInfoCertificateShow());
        if (StringUtils.isNotBlank(payConfig.getThemeColor())) {
            res.setThemeColor(payConfig.getThemeColor());
        } else {
            res.setThemeColor(activityInfo.getThemeColor());
        }
        if (StringUtils.isNotBlank(payConfig.getColorValueUserInfo())) {
            res.setColorValueUserInfo(payConfig.getColorValueUserInfo());
        } else {
            res.setColorValueUserInfo(activityInfo.getColorValueUserInfo());
        }
        res.setAfterSignUpCsDetail(activityInfo.getAfterSignUpCsDetail());
        res.setIncentivesStartTime(activityInfo.getIncentivesStartTime());
        res.setIncentivesEndTime(activityInfo.getIncentivesEndTime());
//        //0:未领取,1:已经领取,未支付,2:已支付,3:未开始,4:领取结束
        if (hasOrder.get() && rewardType == 0) {
            res.setShowDigitCa(false);
            res.setShowMyOrders(true);
        }
        res.setName(name);
        res.setShowPayComplaintButton(payConfig.getShowPayComplaintButton());
        res.setHasCycleTime(payConfig.getHasCycleTime());
        res.setCycleTime(payConfig.getCycleTime());
        res.setFrontConfig(payConfig.getFrontConfig());
        log.info(":>>> 处理活动领取奖励耗时:{} 毫秒", new Date().getTime() - currentTime);
        return res;
    }

    @Override
    public ActivityTaskDataDomain getActivityTaskDataDomain(ActivityInfo activityInfo, String userId) {
        try {
            // 邀请任务
            ActivityRecieveRule recieveRule = activityRecieveRuleService.findByActivityId(activityInfo.getId());
            ActivityTaskInfo taskInfo = this.getActivityTaskInfo(activityInfo.getId(), TaskBizType.INVITE);
            Query queryUp = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityInfo.getId()));

            UserParticipateActivityInfo up = mongoTemplate.findOne(queryUp, UserParticipateActivityInfo.class);
            if (Objects.isNull(up)) {
                up = new UserParticipateActivityInfo();
                up.setActivityId(activityInfo.getId());
                up.setUserId(userId);
            }

            List<String> uids = visitorUserService.findCorrentUserId(userId);
            Double q = 0.0D;
            if (Arrays.asList(QQ_MINI_ACTIVITY_TYPE).contains(activityInfo.getType()) && Boolean.TRUE.equals(activityInfo.getHasPoint())) {
                Long c = userInviteRecordService.getInviteUserCount(userId, activityInfo.getId(), taskInfo.getId(), true);
                log.info(":>>> 用户:{},活动:{} 邀请人数:{}", userId, activityInfo.getId(), c);
                q = Double.valueOf(c + "");
            } else if (Boolean.TRUE.equals(activityInfo.getHasPoint()) && ("contest-plus".equals(activityInfo.getType()) || "qq-mini-plus-noncontest".equals(activityInfo.getType()))) {
                UserActivityPointRanking ranking = userActivityPointRankingService.find(userId, "", activityInfo.getId());
                if (Objects.nonNull(ranking)) {
                    q = ranking.getQuantity();
                    log.info(":>>> 用户:{} 活动:{} 积分排行榜积分:{}", userId, activityInfo.getId(), q);
                }
            } else {
                q = this.getTaskQuantityByUids(activityInfo.getId(), taskInfo.getId(), uids);
            }
            ActivityRewardRule activityRewardRule = new ActivityRewardRule();
            // 设置线下任务
            this.setOffLine(activityInfo, activityRewardRule, up, userId);
            this.setVolunteerWelfare(activityInfo, activityRewardRule, up, userId);
            this.setBroadcast(activityInfo, activityRewardRule, up, userId);
            activityRewardRule.setToMatchValue(q);
            if (Boolean.TRUE.equals(activityInfo.getHasQa())) {
                if (Objects.isNull(up.getPassed())) {
                    activityRewardRule.setQaStatus(Boolean.FALSE);
                } else {
                    activityRewardRule.setQaStatus(up.getPassed());
                }
            }
            activityRewardRule.setActivityId(activityInfo.getId());
            activityRewardRule.setTaskId(taskInfo.getId());
            ActivityRewardRule rule = activityRewardRuleService.match(activityInfo.getId(), taskInfo.getId(), activityInfo.getHasQa() && activityInfo.getCaRules().contains(TaskBizType.QA), activityInfo.getHasOffLine() && activityInfo.getCaRules().contains(TaskBizType.OFF_LINE), activityRewardRule);
            ActivityTaskDataDomain d = this.getTaskDataDomain(taskInfo, userId, rule, new ArrayList<>());
            if (Objects.nonNull(d)) {
                d.setActivityRewardRule(activityRewardRule);
                log.info(":>>> 活动配置志愿者活动证书:{},{}", activityInfo.getId(), d.getCaName());
            }
            log.info(":>>> 活动配置答题可获得证书:{},{}", activityInfo.getId(), activityInfo.getDoQaHasCa());
            if (Boolean.TRUE.equals(activityInfo.getDoQaHasCa())) {

                log.info(":>>> 活动配置了答题可获得证书:{}", activityInfo.getId());
                if (Boolean.TRUE.equals(activityInfo.getHasMultiQa())) {
                    List<UserQaInfo> userQaInfos = this.getUserQas(userId, activityInfo.getId());
                    if (Objects.nonNull(userQaInfos) && !CollectionUtils.isEmpty(userQaInfos)) {
                        d.setContestCaName(userQaInfos.get(0).getCaName());
                        for (UserQaInfo userQaInfo : userQaInfos) {
                            d.getQaCas().put(userQaInfo.getNo(), userQaInfo);
                        }
                    } else {
                        d.setContestCaName("暂无证书");
                    }

//                d.setContestCaName(userParticipateActivityInfo.getContestCaName());
                } else {
                    String contestCaName = activityQaRuleService.getQaCa(activityInfo.getId(), null, up.getQaScore().intValue());
                    d.setContestCaName(contestCaName);
                }
                if (StringUtils.isBlank(d.getContestCaName())) {
                    d.setContestCaName("暂无证书");
                }
            }
            log.info(":>>> 活动:{},答题是否可获得证书:{},是否有多级答题:{},答题获得的证书:{}", activityInfo.getId(), activityInfo.getDoQaHasCa(), activityInfo.getHasMultiQa(), d.getContestCaName());
            // 普及发证书,没有获得证书也提供证书

            if (Objects.nonNull(recieveRule)) {
                if (Boolean.TRUE.equals(recieveRule.getPopularCa()) && ("暂无证书".equals(d.getCaName()) || "无".equals(d.getCaName()))) {
                    if (!CollectionUtils.isEmpty(recieveRule.getPopularCaNames())) {
                        d.setCaName(recieveRule.getPopularCaNames().get(0));
                        log.info(":>>> 活动领取规则为发放普及志愿者证书:{},默认证书名字:{}", activityInfo.getId(), recieveRule.getPopularCaNames().get(0));
                        d.setQ(recieveRule.getQ());
                    }
                }
                if (Boolean.TRUE.equals(recieveRule.getDoubleCa())) {
                    log.info(":>>> 活动领取规则为双证:{}", activityInfo.getId());
                    if (StringUtils.isNotBlank(recieveRule.getReplacedCaName()) && d.getCaName().contains(recieveRule.getReplacedCaName())) {
                        if (StringUtils.isNotBlank(recieveRule.getReplaceByCaName())) {
                            d.setCaName(d.getCaName().replace(recieveRule.getReplacedCaName(), recieveRule.getReplaceByCaName()));
                        }
                    }
                }
                if (Boolean.TRUE.equals(recieveRule.getPopularQaCa()) && ("暂无证书".equals(d.getCaName()) || "无".equals(d.getCaName()))) {
                    if (!CollectionUtils.isEmpty(recieveRule.getPopularCaNames()) && recieveRule.getPopularCaNames().size() > 1) {
                        d.setCaName(recieveRule.getPopularCaNames().get(1));
                        log.info(":>>> 活动领取规则为发放普及志愿者证书:{},默认证书名字:{}", activityInfo.getId(), recieveRule.getPopularCaNames().get(0));
                        d.setQ(recieveRule.getQ());
                    }
                }
                log.info(":>>> 证书名:{},领取规则:{},是否升级:{},是否完成志愿者服务:{}", d.getCaName(), JSON.toJSONString(recieveRule), recieveRule.getUpGradeLevel(), activityRewardRule.getOffLineStatus());
            }
            if (Objects.nonNull(recieveRule) && Boolean.TRUE.equals(recieveRule.getUpGradeLevel())) {
                String caName = d.getCaName();
                if (StringUtils.isNotBlank(caName) && Boolean.TRUE.equals(activityRewardRule.getOffLineStatus())) {
                    log.info(":>>> 证书:{},完成志愿服务,进行等级升级");
                    switch (caName) {
                        case "正式志愿者证书":
                            caName = "优秀志愿者证书";
                            break;
                        case "优秀志愿者证书":
                            caName = "杰出志愿者证书";
                            break;
                        case "杰出志愿者证书":
                            caName = "特别贡献志愿者证书";
                            break;
                        case "特别贡献志愿者证书":
                            caName = "卓越贡献志愿者证书";
                            break;
                        case "卓越贡献志愿者证书":
                            caName = "卓越贡献志愿者证书";
                        default:
                            break;
                    }
                    d.setCaName(caName);
                }
            }
            Long invitedNum = userInviteRecordService.getInviteUserCount(userId, activityInfo.getId(), taskInfo.getId(), true);
            if (Objects.nonNull(invitedNum)) {
                d.setInviteNum(invitedNum.intValue());
            }
            log.info(":>>> 用户:{},活动:{} 获得证书:{}, 竞赛证书:{}", userId, activityInfo.getId(), d.getCaName(), d.getContestCaName());
            return d;
        } catch (Exception e) {
            log.error(":>>> 获取domain信息为空:{}", e);
            ActivityTaskDataDomain d = new ActivityTaskDataDomain();
            d.setCaName("暂无证书");
            return d;
        }

    }

    @Override
    public ActivityTaskDataDomain getActivityOrgTaskDomain(ActivityInfo activityInfo, String userId) {
        // 承办单位
        ActivityTaskInfo taskInfo = this.getActivityTaskInfo(activityInfo.getId(), TaskBizType.ORGANIZER);
        ActivityOrganizerInfo activityOrganizerInfo = activityOrganizerInfoService.find(activityInfo.getId(), userId);
        ActivityRewardRule orgActivityRewardRule = new ActivityRewardRule();
        orgActivityRewardRule.setQaStatus(true);
        orgActivityRewardRule.setOffLineStatus(true);
        Double q = getOrgQ(activityInfo.getId(), taskInfo.getId(), activityOrganizerInfo == null ? null : activityOrganizerInfo.getId());
        // 工作量
        orgActivityRewardRule.setToMatchValue(q == null ? 1 : q + 1);
        orgActivityRewardRule.setActivityId(activityInfo.getId());
        orgActivityRewardRule.setTaskId(taskInfo.getId());

        ActivityRewardRule rule = activityRewardRuleService.match(activityInfo.getId(), taskInfo.getId(), Boolean.FALSE, Boolean.FALSE, orgActivityRewardRule);
        log.info(":>>> 获取申办单位的任务进度:{}", taskInfo.getId());
        ActivityTaskDataDomain d = this.getTaskDataDomain(taskInfo, userId, rule, new ArrayList<>());
        // 设置承办单位任务量
        if (Objects.nonNull(taskInfo)) {
            d.setBizId(taskInfo.getId());
            d.setBizType(taskInfo.getTaskBizType());
        }
        return d;

    }

    @Override
    public UserCaInfoRes getUserCaInfo(String activityId, String taskBizType, String userId, String mobile, String openId) {
        log.info(":>>> 开始获取用户证书信息:{},{},{},{},{}", activityId, taskBizType, userId, mobile, openId);
        if (StringUtils.isBlank(activityId) || StringUtils.isBlank(taskBizType) || StringUtils.isBlank(userId)) {
            log.error(":>>> 获取用户证书信息错误:活动ID、业务类型、用户ID为空");
            throw new BusinessException("获取用户证书信息错误:活动ID、业务类型、用户ID为空");
        }
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        UserCaInfoRes res = new UserCaInfoRes();
        res.setCaDeclare(activityInfo.getPreOrderDesc());
        //来源其他平台业务
        ActivityUserRecord userRes = platformOtherActivityService.findByOpenidOrMoble(activityId, openId, mobile, taskBizType);
        res.setName(userRes.getName());
        res.setMobile(userRes.getMobile());
        res.setUniversityId(userRes.getUniversityId());
        res.setUniversityName(userRes.getUniversityName());
        if (StringUtils.isBlank(userRes.getRecieveName())) {
            res.setRecieveName(userRes.getName());
        } else {
            res.setRecieveName(userRes.getRecieveName());
        }
        if (StringUtils.isBlank(userRes.getRecieveMobile())) {
            res.setRecieveMobile(userRes.getMobile());
        } else {
            res.setRecieveMobile(userRes.getRecieveMobile());
        }
        res.setProvince(userRes.getProvince());
        res.setCity(userRes.getCity());
        res.setArea(userRes.getArea());
        res.setAddress(userRes.getAddress());
        res.setTaskBizType(taskBizType);
        res.setCaName(userRes.getCaLevel());
        res.setMobileVerify(userRes.getMobileVerify());
        res.setCaLevel(userRes.getCaLevel());
        res.setReceiveAddressTips(activityInfo.getReceiveAddressTips());
        return res;
    }

    @Override
    public boolean updateRecieveCaInfo(UserCaInfoRes req, String userId, String openId) {
        log.info(":>>> 更新证书领取信息:{}---> {}", JSON.toJSONString(req), userId);
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(userId)) {
            log.error(":>>> 更新证书领取信息错误:证书信息或用户ID为空");
            throw new BusinessException("更新证书领取信息错误:证书信息或用户ID为空");
        }
        return platformOtherActivityService.update(req, userId, openId);
    }

    @Override
    public ActivityRewadDomain getPreCaInfo(String activityId, String userId, String openId, String taskBizType, String mobile) {
        log.info(":>>> 开始获取证书信息:{},{},taskBizType:{} mobile {}", activityId, userId, openId, taskBizType, mobile);
        if (StringUtils.isBlank(activityId) || StringUtils.isBlank(userId)) {
            log.error(":>>> 获取证书信息错误:活动ID或用户ID为空");
            throw new BusinessException("获取证书信息错误:活动ID或用户ID为空");
        }
        PayConfigPage payConfigPage = activityPayConfigService.findByActivityId(activityId, 0);
        String level = "";
        try {
            ActivityUserRecord activityRecord = platformOtherActivityService.findByOpenidOrMoble(activityId, openId, mobile, taskBizType);
            level = activityRecord.getCaLevel();

        } catch (Exception e) {
            throw new BusinessException("对不起,你未报名");
        }
        ActivityInfo activityInfo = this.findOne(activityId);
        if (Objects.isNull(activityInfo)) {
            throw new BusinessException("当前活动不存在");
        }
        ActivityRewadDomain res = new ActivityRewadDomain();
        PayButtonConfigPage payButtonConfig = payConfigPage.getPayButtonConfigList().stream().filter(payButtonConfigPage -> StringUtils.isNotBlank(payButtonConfigPage.getCaType()) && payButtonConfigPage.getCaType().equals(taskBizType)).findFirst().orElse(null);
        if (Objects.nonNull(payButtonConfig) && StringUtils.isNotBlank(payButtonConfig.getItemDetail())) {
            res.setPreOrderDesc(payButtonConfig.getItemDetail());
        } else {
            res.setPreOrderDesc(payConfigPage.getCertificateDesc());
        }
        CaGroupInfo caGroupInfo = cacheCaGroupInfoService.findByActivityIdAndTaskBizType(activityId, taskBizType);
        if (Objects.isNull(caGroupInfo)) {
            log.error(":>>> 证书分组配置错误:请联系管理员");
            throw new BusinessException("证书分组配置错误:请联系管理员");
        }
        log.info(":>>> 用户:{},活动:{},证书级别:{}", userId, activityId, level);
        List<CaInfo> caInfos = cacheCaInfoService.findByGroupIdAndLevel(caGroupInfo.getId(), level);
        if (!CollectionUtils.isEmpty(caInfos)) {
            caInfos.stream().forEach(caInfo -> {
                //不允许超卖
                if (!caInfo.getCanOverbought()) {
                    List<String> itemMaterialIdList = caInfo.getItemMaterialList();
                    if (!CollectionUtils.isEmpty(itemMaterialIdList)) {
                        //不允许超卖情况
                        long count = itemMaterialIdList.stream().filter(itemMaterialId -> caMaterialConfigService.overbought(itemMaterialId)).count();
                        if (count > 0) {
                            caInfo.setOnSale(Boolean.FALSE);
                        } else {
                            List<CaMaterialConfig> materialList = caMaterialConfigService.findByCaMaterialIdList(itemMaterialIdList);
                            long stockCountZero = materialList.stream().filter(caMaterialConfig -> (caMaterialConfig.getStockCount() - caMaterialConfig.getSoldCount()) <= 0).count();
                            if (stockCountZero > 0) {
                                caInfo.setOnSale(Boolean.FALSE);
                            }
                        }
                    }
                }
                if (!CollectionUtils.isEmpty(caInfo.getGiftItems())) {
                    //设置赠品是否超卖
                    for (GiftCaInfo giftItem2 : caInfo.getGiftItems()) {
                        CaInfo giftCaInfo = this.mongoTemplate.findById(giftItem2.getId(), CaInfo.class);
                        if (Objects.nonNull(giftCaInfo) && !giftCaInfo.getCanOverbought()) {
                            List<String> itemMaterialIdList = giftCaInfo.getItemMaterialList();
                            List<CaMaterialConfig> giftItemMaterialList = caMaterialConfigService.findByCaMaterialIdList(itemMaterialIdList);
                            long giftItemStockCountZero = giftItemMaterialList.stream().filter(caMaterialConfig -> (caMaterialConfig.getStockCount() - caMaterialConfig.getSoldCount()) <= 0).count();
                            if (giftItemStockCountZero > 0) {
                                caInfo.setOnSale(Boolean.FALSE);
                                break;
                            }
                        }
                        if (Objects.nonNull(giftCaInfo) && !giftCaInfo.getOnSale()) {
                            caInfo.setOnSale(Boolean.FALSE);
                            break;
                        }
                    }
                }
            });
            res.setCaInfos(caInfos.stream().filter(caInfo -> caInfo.getPrice() > 0).collect(Collectors.toList()));
        }
        res.setActivityId(activityId);
        res.setUserId(userId);
        res.setCaLevel(level);
        res.setLevelShow(payButtonConfig.getLevelShow());
        res.setShowCountDown(payConfigPage.getShowCountDown());
        res.setBuyMultiCA(caGroupInfo.getBuyMultiCA());
        res.setIncentivesStartTime(activityInfo.getIncentivesStartTime());
        res.setIncentivesEndTime(activityInfo.getIncentivesEndTime());
        res.setCountdownColor(payConfigPage.getCountdownColor());
        res.setLevelColor(payConfigPage.getLevelColor());
        return res;
    }

    @Override
    public boolean reeDataProvince(String activityId, String taskId) {
        Long count = userActivityTaskRankingService.countByActivityIdAndTaskId(activityId, taskId);
        if (count.equals(0L)) {
            return true;
        }
        HashMap<String, UniversityInfo> uMap = new HashMap<>();
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("taskId").is(taskId));
        log.info(":>>> 活动ID:{},{},{}", activityId, taskId, count);
        Integer pageSize = 100;
        for (int i = 0; i < count.intValue() / pageSize + 1; i++) {
            log.info(":>>> 开始处理第:{} 页", i);
            query.limit(pageSize);
            query.skip(i * pageSize);
            List<UserActivityTaskRanking> datas = userActivityTaskRankingService.find(query);
            if (CollectionUtils.isEmpty(datas)) {
                log.error(":>>> 已经没有数据了:{}", i);
                continue;
            }
            for (UserActivityTaskRanking userActivityTaskRanking : datas) {
                Query queryUp = new Query().addCriteria(Criteria.where("activityId").is(userActivityTaskRanking.getActivityId()).and("userId").is(userActivityTaskRanking.getUserId()));
                UserParticipateActivityInfo up = mongoTemplate.findOne(queryUp, UserParticipateActivityInfo.class);
                if (Objects.nonNull(up) && StringUtils.isNotBlank(up.getUniversityId())) {
                    UniversityInfo universityInfo = null;
                    if (uMap.containsKey(up.getUniversityId())) {
                        universityInfo = uMap.get(up.getUniversityId());
                    } else {
                        Query query1 = new Query().addCriteria(Criteria.where("id").is(up.getUniversityId()));
                        universityInfo = mongoTemplate.findOne(query1, UniversityInfo.class);
                        if (Objects.nonNull(universityInfo)) {
                            uMap.put(up.getUniversityId(), universityInfo);
                        }
                    }
                    if (Objects.nonNull(universityInfo) && StringUtils.isNotBlank(universityInfo.getProvince()) && !universityInfo.getProvince().equals(userActivityTaskRanking.getProvince())) {
                        UserActivityTaskRanking update = new UserActivityTaskRanking();
                        update.setId(userActivityTaskRanking.getId());
                        update.setProvince(universityInfo.getProvince());
                        update.setProvinceBack(userActivityTaskRanking.getProvince());
                        userActivityTaskRankingService.updateById(update);
                        log.info(":>>> 用户:{} 省:{} 有问题,更新为:{}", userActivityTaskRanking.getUserId(), userActivityTaskRanking.getProvince(), universityInfo.getProvince());
                    }
                }
            }
        }
        return true;
    }

    @Override
    public ActivitySignUpRequest getActivitySignUpInfo(String userId, String mobile, String activityId, Integer type) {
        log.info(":>>> 开始获取用户报名信息:{}", userId);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(activityId)) {
            log.error(":>>> 用户ID:{} 为空或activityId 为空", userId);
            throw new BusinessException("获取用户报名信息参数错误");
        }
        ActivityInfo activityInfo = cacheActivityService.findById(activityId);
        //PlatformConfig config = mongoTemplate.findOne(queryPlatform, PlatformConfig.class);
        boolean check = visitorUserService.checkedMobile(userId);
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("joined").is(Boolean.TRUE));
        if (type == 2) {
            query.addCriteria(Criteria.where("activityId").is(activityId));
        }
//        query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "id")));
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        query.with(sort);
        UserParticipateActivityInfo exist = mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.nonNull(exist)) {
            log.error(":>>> 用户已经参与该活动:{},不需要验证手机号", exist.getActivityId());
            ActivitySignUpRequest res = new ActivitySignUpRequest();
            res.setName(exist.getName());
            res.setMobile(exist.getMobile());
            res.setUniversityId(exist.getUniversityId());
            res.setUniversityName(exist.getUniversityName());
            res.setProvince(exist.getProvince());
            res.setCity(exist.getCity());
            res.setFullAddress(exist.getAddress());
            res.setArea(exist.getArea());
            res.setQq(exist.getQq());
            res.setMustCode(!check);
            res.setGrade(exist.getGrade());
            res.setAfterQaTips(activityInfo.getSignUpTips());
            res.setSignUpInputUniversity(activityInfo.getSignUpInputUniversity());
            res.setChinaWebsite(activityInfo.getChinaWebsite());
            log.info(":>>> 返回的报名信息:{}", JSON.toJSONString(res));
            return res;
        }
        Query queryU = new Query().addCriteria(Criteria.where("accountInfoId").is(userId));
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("mobile").ne(null), Criteria.where("mobile").ne(""));
        queryU.addCriteria(criteria);
        WechatH5UserPO wechatH5UserPO = mongoTemplate.findOne(queryU, WechatH5UserPO.class);
        if (Objects.nonNull(wechatH5UserPO)) {
            ActivitySignUpRequest res = new ActivitySignUpRequest();
            res.setName(wechatH5UserPO.getName());
            res.setMobile(wechatH5UserPO.getMobile());
            res.setMustCode(!check);
            res.setAfterQaTips(activityInfo.getSignUpTips());
            res.setSignUpInputUniversity(activityInfo.getSignUpInputUniversity());
            res.setChinaWebsite(activityInfo.getChinaWebsite());
            log.error(":>>> 用户手机号非空 {},不需要验证手机号", userId);
            return res;
        }
        ActivitySignUpRequest res = new ActivitySignUpRequest();
        log.info(":>>> 用户手机号空 {},需要验证手机号", userId);
        res.setMustCode(!check);
        res.setChinaWebsite(activityInfo.getChinaWebsite());
        res.setAfterQaTips(activityInfo.getSignUpTips());
        return res;
    }

    @Override
    public QaTaskRes queryQaTask(String activityId, Integer no, String userId) {
        log.info(":>>> 开始获取用户答题任务:{},{},no:{}", activityId, userId, no);
        if (StringUtils.isBlank(activityId) || StringUtils.isBlank(userId)) {
            log.error(":>>> 参数错误:活动ID或用户ID为空");
            throw new BusinessException("参数错误:活动ID或用户ID为空");
        }
        UserQaInfo currentQa = this.getUserQa(userId, activityId);
        Query queryAll = new Query().addCriteria(Criteria.where("activityId").is(activityId));
        List<ActivityQaInfo> qaInfos = mongoTemplate.find(queryAll, ActivityQaInfo.class);
        if (Objects.isNull(qaInfos)) {
            qaInfos = new ArrayList<>();
        }
        ActivityInfo activityInfo = this.findOne(activityId);

        UserParticipateActivityInfo up = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId)), UserParticipateActivityInfo.class);
        if ("1".equals(activityInfo.getQaMode()) && Objects.isNull(up)) {
            log.error(":>>> 用户:{} 未参与活动:{}", userId, activityId);
            throw new BusinessException("用户未参与活动");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId));
        if (Objects.nonNull(no)) {
            query.addCriteria(Criteria.where("no").is(no));
        }
//        query.with(new Sort(new Sort.Order(Sort.Direction.ASC, "no")));
        Sort sort = Sort.by(Sort.Direction.ASC, "no");
        query.with(sort);
        ActivityQaInfo activityQaInfo = mongoTemplate.findOne(query, ActivityQaInfo.class);
        QaTaskRes qaTaskRes = new QaTaskRes();
        qaTaskRes.setTotal(activityInfo.getQaOrder());
        if (Objects.isNull(activityQaInfo)) {
            log.error(":>>> 活动没有配置答题:{}", activityId);
            throw new BusinessException("活动没有配置答题");
        }
        Query queryU = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityQaInfoId").is(activityQaInfo.getId()));
        UserQaInfo userQaInfo = mongoTemplate.findOne(queryU, UserQaInfo.class);
        if (Objects.isNull(currentQa)) {
            qaTaskRes.setCurrentQa(1);
        } else {
            if (currentQa.getNo().intValue() == activityInfo.getQaOrder()) {
                qaTaskRes.setCurrentQa(currentQa.getNo());
            } else {
                qaTaskRes.setCurrentQa(currentQa.getNo() + 1);
            }
        }

        qaTaskRes.setActivityId(activityId);
        qaTaskRes.setActivityName(activityInfo.getName());
        qaTaskRes.setTotal(qaInfos.size());
        if (Objects.isNull(userQaInfo)) {
            userQaInfo = new UserQaInfo();
            userQaInfo.setActivityId(activityId);
            userQaInfo.setUserId(userId);
            userQaInfo.setActivityQaInfoId(activityQaInfo.getId());
            userQaInfo.setCaName("暂无证书");
            userQaInfo.setPassed(false);
            userQaInfo.setNo(activityQaInfo.getNo());
            userQaInfo.setActivityQaInfo(activityQaInfo);
            userQaInfo.setReTryQaNum(activityQaInfo.getTotalQaNum());
            userQaInfo.setMaxScore(0D);
        } else {
            userQaInfo.setNo(activityQaInfo.getNo());
            userQaInfo.setMaxScore(userQaInfo.getQaScore());
        }
        userQaInfo.setActivityQaInfo(activityQaInfo);
        qaTaskRes.getDatas().put("" + activityQaInfo.getNo(), userQaInfo);
        qaTaskRes.getStr().put("" + activityQaInfo.getNo(), activityQaInfo.getName());
        if (Objects.isNull(currentQa)) {
            qaTaskRes.setCurrentQa(1);
        } else {
            if (currentQa.getNo().intValue() == activityInfo.getQaOrder()) {
                qaTaskRes.setCurrentQa(currentQa.getNo());
            } else {
                qaTaskRes.setCurrentQa(currentQa.getNo() + 1);
            }
        }
        for (ActivityQaInfo qaInfo : qaInfos) {
            if (!activityQaInfo.getNo().equals(qaInfo.getNo())) {
                UserQaInfo u = new UserQaInfo();
                u.setActivityId(activityId);
                u.setUserId(userId);
                u.setActivityQaInfoId(activityQaInfo.getId());
                u.setCaName("暂无证书");
                u.setPassed(false);
                u.setNo(activityQaInfo.getNo());
                u.setActivityQaInfo(activityQaInfo);
                u.setReTryQaNum(activityQaInfo.getTotalQaNum());
                u.setMaxScore(0D);
                u.setLimitTime(qaInfo.getLimitTime());
                u.setLimitTimed(qaInfo.getLimitTimed());
                u.setActivityQaInfo(qaInfo);
                qaTaskRes.getDatas().put("" + qaInfo.getNo(), u);
                qaTaskRes.getStr().put("" + qaInfo.getNo(), qaInfo.getName());
            }
        }
        return qaTaskRes;
    }

    @Override
    public ActivityTaskInfo queryTask(String activityId, TaskBizType taskBizType) {
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId)
                .and("taskBizType").is(taskBizType)
                .and("deleted").is(Boolean.FALSE)
                .and("opened").is(Boolean.TRUE)
        );
        ActivityTaskInfo taskInfo = mongoTemplate.findOne(query, ActivityTaskInfo.class);
        return taskInfo;
    }

    @Override
    public MultiQaRes doMultiQa(UserDoQaVO req) {
        log.info(":>>> 开始提交多级答题:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getUserId()) || CollectionUtils.isEmpty(req.getQas()) || StringUtils.isBlank(req.getActivityQaInfoId())) {
            log.error(":>>> 答题参数错误");
            throw new BusinessException("答题参数错误");
        }
        ActivityInfo activityInfo = this.findOne(req.getActivityId());
        ActivityQaInfo activityQaInfo = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("id").is(req.getActivityQaInfoId())), ActivityQaInfo.class);
        if (Objects.isNull(activityQaInfo)) {
            log.error(":>>> 题库不存在:{}", req.getActivityQaInfoId());
            throw new BusinessException("题库不存在");
        }
        Double score = this.computeQaScore(req);
        UserParticipateActivityInfo participateActivityInfo = this.getUserParticipateActivityInfo(req.getUserId(), req.getActivityId());
        if (Objects.isNull(participateActivityInfo)) {
            log.info(":>>> 用户:{} 未报名:{} 活动", req.getUserId(), req.getActivityId());
            // 活动为先答题后报名
            if ("0".equals(activityInfo.getQaMode())) {
                participateActivityInfo = new UserParticipateActivityInfo();
                participateActivityInfo.setActivityId(req.getActivityId());
                participateActivityInfo.setUserId(req.getUserId());
                participateActivityInfo.setCreatedTime(new Date());
                participateActivityInfo.setJoined(false);
                participateActivityInfo.setTotalQaNum(activityQaInfo.getTotalQaNum());
                participateActivityInfo.setPassQaScore(activityQaInfo.getPassQaScore());
                participateActivityInfo.setCurrentQaScore(score);
                participateActivityInfo.setQaScore(score);
                participateActivityInfo.setUnionId(req.getUserPO().getUnionId());
                participateActivityInfo.setOpenId(req.getUserPO().getOpenId());
                participateActivityInfo.setAvatarUrl(req.getUserPO().getAvatarUrl());
                participateActivityInfo.setAppId(req.getUserPO().getAppId());
                participateActivityInfo.setPlatform(req.getUserPO().getCurrentPlatform());
                participateActivityInfo = mongoTemplate.insert(participateActivityInfo);
                log.info(":>>> 用户:{} 未报名:{} 活动,创建报名信息:{}", req.getUserId(), req.getActivityId(), JSON.toJSONString(participateActivityInfo));
            } else {
                log.error(":>>> 用户:{} 未报名:{} 活动,不能答题", req.getUserId(), req.getActivityId());
                throw new BusinessException("用户未报名活动,不能参与答题");
            }
        }
        log.info(":>>> 用户:{},答题的最终得分为:{}", req.getUserId(), score);
        String qaCaName = activityQaRuleService.getQaCa(req.getActivityId(), req.getActivityQaInfoId(), score.intValue());
        log.info(":>>> 用户:{},活动:{},答题:{},得分:{},通过分数:{}", req.getUserId(), req.getActivityId(), req.getActivityQaInfoId(), score, activityQaInfo.getPassQaScore());
        Query queryUserQa = new Query().addCriteria(Criteria.where("userId").is(req.getUserId()).and("activityQaInfoId").is(req.getActivityQaInfoId()));
        UserQaInfo userQaInfo = mongoTemplate.findOne(queryUserQa, UserQaInfo.class);
        Boolean passed = Boolean.FALSE;
        if (Objects.nonNull(activityQaInfo.getPassQaScore()) && score.intValue() >= activityQaInfo.getPassQaScore().intValue()) {
            passed = Boolean.TRUE;
        }
        log.info(":>>> 用户:{} 活动:{},及格分数:{},得分:{},是否通过:{}", req.getUserId(), req.getActivityId(), activityQaInfo.getPassQaScore(), score, passed);
        if (Objects.isNull(userQaInfo)) {
            log.info(":>>> 用户:{} 活动:{},题库:{} 答题历史为空", req.getUserId(), req.getActivityId(), req.getActivityQaInfoId());
            userQaInfo = new UserQaInfo();
            userQaInfo.setActivityId(req.getActivityId());
            userQaInfo.setUserId(req.getUserId());
            userQaInfo.setNo(activityQaInfo.getNo());
            userQaInfo.setQaScore(score);
            userQaInfo.setCaName(qaCaName);
            userQaInfo.setReTryQaNum(activityQaInfo.getTotalQaNum().intValue() == 1 ? 0 : activityQaInfo.getTotalQaNum() - 1);
            userQaInfo.setTotalQaNum(activityQaInfo.getTotalQaNum());
            userQaInfo.setCreatedTime(new Date());
            userQaInfo.setActivityQaInfoId(req.getActivityQaInfoId());
            userQaInfo.setPassed(passed);
            userQaInfo.setCurrentQaScore(score);
            userQaInfo = mongoTemplate.insert(userQaInfo);
            log.info(":>>> 用户:{},活动:{},题库:{},是否通过:{},是否参与活动:{},答题是否可更新:{}", req.getUserId(), activityInfo.getId(), req.getActivityQaInfoId(), participateActivityInfo.getJoined());
            if (Objects.nonNull(participateActivityInfo) && !participateActivityInfo.getAccumulateQ() && Boolean.TRUE.equals(activityInfo.getAccumulate()) && Boolean.TRUE.equals(passed) && Boolean.TRUE.equals(participateActivityInfo.getJoined())) {
                this.accumulateQaQ(activityInfo, req.getUserId(), req.getUserPO());
                userQaInfo.setAccumulateQ(true);
                userQaInfo.setUpdatedTime(new Date());
                mongoTemplate.save(userQaInfo);
            }
            return buildMultiQaRes(userQaInfo, activityQaInfo, activityInfo.getQaOrder());
        }
        log.info(":>>> 用户:{} 之前参与过活动答题:{}", req.getUserId(), req.getActivityId());
        if (userQaInfo.getReTryQaNum() <= 0) {
            log.error(":>>> 用户:{},题库:{} 已经超过答题次数", req.getUserId(), req.getActivityQaInfoId());
            throw new BusinessException("已经超过答题次数,请联系客服!");
        }
        if (Boolean.TRUE.equals(activityQaInfo.getQaAccumulation())) {
            log.error(":>>> 活动:{} 配置答题可累加:{}", req.getActivityId(), req.getUserId());
            if (score.compareTo(userQaInfo.getQaScore()) == 1) {
                userQaInfo.setQaScore(score);
                userQaInfo.setUpdatedTime(new Date());
                userQaInfo.setCaName(qaCaName);
                userQaInfo.setPassed(passed);
            }
            userQaInfo.setReTryQaNum((userQaInfo.getReTryQaNum() == null || userQaInfo.getReTryQaNum().intValue() == 1) ? 0 : userQaInfo.getReTryQaNum() - 1);
            mongoTemplate.save(userQaInfo);
        }
        userQaInfo.setCurrentQaScore(score);
        log.info(":>>> 用户:{},活动:{},题库:{},是否通过:{},是否参与活动:{},答题是否可更新:{},用户是否已经更新贡献值:{}", req.getUserId(), activityInfo.getId(), req.getActivityQaInfoId(), passed, participateActivityInfo.getJoined(), activityQaInfo.getQaAccumulation(), userQaInfo.getAccumulateQ());
        if (Objects.nonNull(participateActivityInfo) && !participateActivityInfo.getAccumulateQ() && Boolean.TRUE.equals(activityQaInfo.getQaAccumulation()) && Boolean.FALSE.equals(userQaInfo.getAccumulateQ()) && Boolean.TRUE.equals(passed) && Boolean.TRUE.equals(participateActivityInfo.getJoined()) && Boolean.TRUE.equals(activityInfo.getAccumulate())) {
            this.accumulateQaQ(activityInfo, req.getUserId(), req.getUserPO());
            userQaInfo.setAccumulateQ(true);
            userQaInfo.setUpdatedTime(new Date());
            userQaInfo.setPassed(Boolean.TRUE);
            mongoTemplate.save(userQaInfo);
        }
        return buildMultiQaRes(userQaInfo, activityQaInfo, activityInfo.getQaOrder());
    }


    @Override
    public ActivityInfo getActivityInfo(String activityId) {
        log.info(":>>> 开始获取活动信息:{}", activityId);
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 活动信息为空:");
            throw new BusinessException("获取活动信息参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(activityId));
        ActivityInfo activityInfo = mongoTemplate.findOne(query, ActivityInfo.class);
        return activityInfo;
    }

    /**
     * 补偿答题数据
     *
     * @param activityId
     */
    private void reeQa(String activityId, String taskId, UserPO userPO) {
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("joined").is(Boolean.TRUE).and("passed").is(Boolean.TRUE));
        log.info(":>>> 活动ID:{}", activityId);
        // 设置省查询
        Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
        query.with(sort);
        Long count = mongoTemplate.count(query, UserParticipateActivityInfo.class);
        log.info(":>>> 活动:{} 参与人数为:{}", activityId, count);
        Integer pageSize = 10;
        for (int i = 0; i < count.intValue() / pageSize + 1; i++) {
            PageRequest pageRequest = PageRequest.of(i, pageSize);
            List<UserParticipateActivityInfo> rankings = mongoTemplate.find(query.with(pageRequest), UserParticipateActivityInfo.class);
            log.info(":>>> 开始处理第:{} 页,数量为:{}", i, rankings == null ? 0 : rankings.size());
            if (CollectionUtils.isEmpty(rankings)) {
                continue;
            }
            for (UserParticipateActivityInfo u : rankings) {
                Double q = getUserQ(activityId, taskId, userPO.getId(), u);
                UserActivityTaskRanking userActivityTaskRanking = userActivityTaskRankingService.findByActivityIdAndTaskIdAndUserId(activityId, taskId, u.getUserId());
                if (Objects.isNull(userActivityTaskRanking)) {
                    log.info(":>>> 用户:{},答题通过,但是未累加排行榜", u.getUserId());
                    UniversityInfo universityInfo = null;
                    if (StringUtils.isNotBlank(u.getUniversityId())) {
                        Query queryU = new Query().addCriteria(Criteria.where("id").is(u.getUniversityId()));
                        universityInfo = mongoTemplate.findOne(queryU, UniversityInfo.class);

                    }
                    UserActivityTaskRanking ranking = new UserActivityTaskRanking();
                    ranking.setActivityId(activityId);
                    ranking.setUserId(u.getUserId());
                    ranking.setTaskId(taskId);
                    ranking.setTaskBizType(TaskBizType.INVITE);
                    ranking.setCreatedTime(new Date());
                    if (Objects.nonNull(universityInfo)) {
                        if (!StringUtils.isBlank(ranking.getProvince())) {
                            ranking.setProvince(universityInfo.getProvince());
                        }
                        ranking.setUniversityName(universityInfo.getName());
                        ranking.setUniversityId(universityInfo.getId());
                    }
                    ranking.setProvince(universityInfo.getProvince());
                    ranking.setImageUrl(userPO.getAvatarUrl());
                    ranking.setName(userPO.getNickName());
                    ranking.setQuantity(q);
                    ranking.setUniversityLogo(universityInfo.getLogo());
                    userActivityTaskRankingService.insert(ranking);
                    log.info(":>>> 插入用户排行榜:{}", u.getUniversityId());
                } else {
                    if (Objects.isNull(userActivityTaskRanking.getQuantity())) {
                        log.error(":>>> 用户排行榜:{},数据为空", userActivityTaskRanking.getUserId());
                        continue;
                    }
                    if (userActivityTaskRanking.getQuantity().compareTo(q) == -1) {
                        log.info(":>>> 用户:{} 值不相等,需要更新:{} --->:{}", u.getUserId(), userActivityTaskRanking.getQuantity(), q);
                        UserActivityTaskRanking update = new UserActivityTaskRanking();
                        update.setId(userActivityTaskRanking.getId());
                        update.setQuantity(q);
                        update.setQuantityBack(userActivityTaskRanking.getQuantity().intValue());
                        userActivityTaskRankingService.updateById(update);

                    }
                }
            }
        }

    }

    private Double getUserQ(String activityId, String taskId, String userId, UserParticipateActivityInfo up) {
        log.info(":>>> 开始处理用户:{}", userId);
        Double points = 0.0D;
        Query queryInvite = new Query();
        queryInvite.addCriteria(Criteria.where("invitedByUserId").is(userId));
        queryInvite.addCriteria(Criteria.where("activityId").is(activityId));
        queryInvite.addCriteria(Criteria.where("taskId").is(taskId));
        queryInvite.addCriteria(Criteria.where("joinStatus").is(Boolean.TRUE));
        Long inviteCount = mongoTemplate.count(queryInvite, UserInviteRecord.class);
        points = points + inviteCount.intValue();
        log.info(":>>> 用户:{} 邀请数量:{}", userId, inviteCount);
        // 线下志愿活动
        ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityId, TaskBizType.OFF_LINE.name());
        log.info(":>>> 活动有线下活动:{},状态:{},{} ", activityId, userId, JSON.toJSONString(printDomain));
        /**
         * 线下组织活动状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
         */
        ActivityTaskRule taskRule = activityTaskRuleService.find(activityId, TaskBizType.OFF_LINE.name());
        if (Objects.nonNull(taskRule)) {
            if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                points = points + taskRule.getPoints();
                log.info(":>>> 用户:{} 线下志愿者活动审核通过累计,加分:{}", userId, taskRule.getPoints());
                // 审核通过
            }
        }
        // 直播
        ActivityFootPrintDomain printDomainB = getActivityFootPrint(userId, activityId, TaskBizType.BROADCASAT.name());
        log.info(":>>> 直播活动:{},状态:{},{} ", activityId, userId, JSON.toJSONString(printDomainB));

        ActivityTaskRule taskRuleB = activityTaskRuleService.find(activityId, TaskBizType.BROADCASAT.name());
        if (Objects.nonNull(taskRuleB)) {
            if (printDomainB.getPassedNum().compareTo(taskRuleB.getThreshold()) != -1) {
                points = points + taskRuleB.getPoints();
                log.info(":>>> 用户:{} 直播活动审核通过累计,加分:{}", userId, taskRuleB.getPoints());
                // 审核通过
            }
        }
        // 福利
        ActivityFootPrintDomain printDomainF = getActivityFootPrint(userId, activityId, TaskBizType.WELFARE.name());
        log.info(":>>> 活动福利:{},状态:{},{} ", activityId, userId, JSON.toJSONString(printDomainF));

        ActivityTaskRule taskRuleF = activityTaskRuleService.find(activityId, TaskBizType.WELFARE.name());
        if (Objects.nonNull(taskRuleF)) {
            if (printDomainF.getPassedNum().compareTo(taskRuleF.getThreshold()) != -1) {
                points = points + taskRuleF.getPoints();
                log.info(":>>> 用户:{} 活动福利审核通过累计,加分:{}", userId, taskRuleF.getPoints());
                // 审核通过
            }
        }
        if (Objects.nonNull(up) && Boolean.TRUE.equals(up.getPassed())) {
            ActivityTaskRule taskRuleQ = activityTaskRuleService.find(activityId, TaskBizType.QA.name());
            if (Objects.nonNull(taskRuleQ)) {
                points = points + taskRuleF.getPoints();
                log.info(":>>> 用户:{} 答题通过累加分数,加分:{}", userId, taskRuleQ.getPoints());
            }
        }
        return points;
    }

    /**
     * 更新活动任务工作量
     *
     * @param userId
     * @param activityId
     * @param taskId
     * @param num
     */
    private void updateTaskQuantity(final String userId, final String activityId, final String taskId, TaskBizType bizType, final Double num) {
        log.info(":>>> 开始更新活动任务工作量:{},{},{},{}", userId, activityId, taskId, num);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(activityId) || StringUtils.isBlank(taskId) || Objects.isNull(num) || Objects.isNull(bizType)) {
            log.error(":>>> 更新活动任务参数错误:用户ID,活动ID,任务ID,数量为空,任务行动类型");
            return;
        }
        Date date = new Date();
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("taskId").is(taskId).and("activityId").is(activityId));
        UserParticipateActivityTaskInfo taskInfo = mongoTemplate.findOne(query, UserParticipateActivityTaskInfo.class);
        if (Objects.isNull(taskInfo)) {
            log.info(":>>> 用户:{} ,参与活动:{},任务:{},业务:{} 不存在，开始创建", userId, activityId, taskId, bizType);
            taskInfo = new UserParticipateActivityTaskInfo();
            taskInfo.setActivityId(activityId);
            taskInfo.setBizType(bizType);
            taskInfo.setTaskId(taskId);
            taskInfo.setUserId(userId);
            taskInfo.setCreatedTime(date);
            taskInfo.setQuantity(num);
            // 开始1等级
            taskInfo.setStep(1);
            mongoTemplate.insert(taskInfo);
        } else {
            Query queryUpdate = new Query().addCriteria(Criteria.where("id").is(taskInfo.getId()));
            Update update = new Update();
            update.inc("quantity", num);
            mongoTemplate.updateFirst(queryUpdate, update, UserParticipateActivityTaskInfo.class);
        }

    }

    /**
     *
     */
    /**
     * 获取活动任务
     * /**
     * * 用户行为类型,share:创意分享,sale:营销,volunteer:志愿者
     */
    private ActivityTaskInfo getActivityTaskInfo(String activityId, TaskBizType userBizType) {
        log.info(":>>> 开始获取活动任务信息:{},{}", activityId, userBizType);
        if (StringUtils.isBlank(activityId) || Objects.isNull(userBizType)) {
            log.error(":>>> 获取活动任务信息:活动ID、类型为空");
            throw new BusinessException("获取活动任务信息:活动ID、类型为空");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("taskBizType").is(userBizType));
        ActivityTaskInfo activityTaskInfo = mongoTemplate.findOne(query, ActivityTaskInfo.class);
        if (Objects.isNull(activityTaskInfo)) {
            log.error(":>>> 数据不存在");
            return null;
//            throw new BusinessException("数据不存在");
        }
        return activityTaskInfo;
    }

    /**
     * 获取活动任务
     *
     * @param activityId
     * @return
     */
    private List<ActivityTaskInfo> getActivityTaskInfo(String activityId) {
        log.info(":>>> 开始获取活动任务信息:{}", activityId);
        if (StringUtils.isBlank(activityId)) {
            log.error(":>>> 获取活动任务信息:活动ID为空");
            throw new BusinessException("获取活动任务信息:活动ID为空");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("status").ne(Boolean.FALSE));
        Sort sort = Sort.by(Sort.Direction.DESC, "priority");
        query.with(sort);
        List<ActivityTaskInfo> activityTaskInfos = mongoTemplate.find(query, ActivityTaskInfo.class);
        log.info(":>>> 活动的:{},的任务数据数量:{}", activityId, activityTaskInfos == null ? 0 : activityTaskInfos.size());
        if (Objects.isNull(activityTaskInfos)) {
            log.error(":>>> 数据不存在");
            throw new BusinessException("数据不存在");
        }
        return activityTaskInfos;
    }

    /**
     * 设置任务明细
     *
     * @param taskInfo
     */
    private void setActivityTaskDetail(ActivityInfo activityInfo, ActivityTaskInfo taskInfo, String userId) {
        log.info(":>>> 开始设置活动任务详情:{},用户:{}", taskInfo == null ? null : taskInfo.getId(), userId);
        if (Objects.isNull(taskInfo) || Objects.isNull(activityInfo)) {
            log.error(":>>> 任务信息为空");
            return;
        }
        switch (taskInfo.getTaskBizType()) {
            case SHARE:
                log.info(":>>> 创意分享类,无需更新");
                break;
            case SALES: {
                log.info(":>>> 大赛类");
                UserPO userPO = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("id").is(userId)), UserPO.class);
                PlayBillDomain playBill = taskInfo.getPlayBill();
                if (Objects.isNull(playBill)) {
                    playBill = new PlayBillDomain();
                }
                playBill.setAvatarUrl(userPO.getAvatarUrl());
                playBill.setNickName(userPO.getNickName());
            }
            break;
            case INVITE: {
                log.info(":>>> 志愿者类,无需更新");
                UserPO userPO = mongoTemplate.findOne(new Query().addCriteria(Criteria.where("id").is(userId)), UserPO.class);
                PlayBillDomain playBill1 = taskInfo.getPlayBill();
                if (Objects.isNull(playBill1)) {
                    playBill1 = new PlayBillDomain();
                }
                playBill1.setAvatarUrl(userPO.getAvatarUrl());
                playBill1.setNickName(userPO.getNickName());
                taskInfo.setPlayBill(playBill1);
            }
            break;
            default:
                break;
        }
    }


    /**
     * 更新用户邀请状态
     *
     * @param id
     */
    private void updateInviteStatus(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        Date now = new Date();
        update.set("joinStatus", true);
        update.set("updatedTime", now);
        update.set("joinTime", now);
        UpdateResult result = mongoTemplate.updateFirst(query, update, UserInviteRecord.class);
        log.info(":>>> 更新:{} 被邀请,记录结果:{}", id, result.getModifiedCount() > 0 ? true : false);
    }

    /**
     * 获取用户被邀请记录:一个活动的任务用户只能被邀请一次
     *
     * @param userId
     * @param activityId
     * @param taskId
     * @return
     */
    private UserInviteRecord getInvitedRecord(String userId, String activityId, String taskId) {
        Query query = new Query().addCriteria(Criteria.where("invitedToUserId").is(userId).and("activityId").is(activityId).and("taskId").is(taskId));
        UserInviteRecord userInviteRecord = masterMongoTemplate.findOne(query, UserInviteRecord.class);
        return userInviteRecord;
    }

    /**
     * 设置排行榜省查询条件
     *
     * @param query
     * @param province
     */
    private String setRankListProvince(Query query, String activityId, String province, UserPO userPO) {
        String res = province;
        Date start = new Date();
        if (StringUtils.isNotBlank(province)) {
            if ("-".equals(province)) {
                Query queryU = new Query().addCriteria(Criteria.where("userId").is(userPO.getId()).and("activityId").is(activityId));
                UserParticipateActivityInfo up = mongoTemplate.findOne(queryU, UserParticipateActivityInfo.class);
                if (Objects.nonNull(up) && StringUtils.isNotBlank(up.getUniversityId())) {
                    Query query1 = new Query().addCriteria(Criteria.where("id").is(up.getUniversityId()));
                    UniversityInfo universityInfo = mongoTemplate.findOne(query1, UniversityInfo.class);
                    if (Objects.nonNull(universityInfo) && StringUtils.isNotBlank(universityInfo.getProvince())) {
                        log.info(":>>> 省查询条件:{}", universityInfo.getProvince());
                        String provinceStr = universityInfo.getProvince();
                        query.addCriteria(Criteria.where("province").is(provinceStr));
                        res = provinceStr;
                    }
                } else {
                    if (StringUtils.isNotBlank(userPO.getUniversityId())) {
                        Query query1 = new Query().addCriteria(Criteria.where("id").is(userPO.getUniversityId()));
                        UniversityInfo universityInfo = mongoTemplate.findOne(query1, UniversityInfo.class);
                        if (Objects.nonNull(universityInfo) && StringUtils.isNotBlank(universityInfo.getProvince())) {
                            log.info(":>>> 省查询条件:{}", universityInfo.getProvince());
                            String provinceStr = universityInfo.getProvince();
                            query.addCriteria(Criteria.where("province").is(provinceStr));
//
                            res = provinceStr;
                        }
                    } else {
                        if (StringUtils.isNotBlank(userPO.getProvince())) {
                            log.info(":>>> 省查询条件:{}", userPO.getProvince());
                            String provinceStr = userPO.getProvince();
                            query.addCriteria(Criteria.where("province").is(provinceStr));
                            res = provinceStr;
                        }
                    }
                }

            } else {
                log.info(":>>> 省查询条件:{}", province);
                query.addCriteria(Criteria.where("province").is(province));
                res = province;
            }
        }
        log.info(":>>> 结束查询省耗时:{} 毫秒", System.currentTimeMillis() - start.getTime());
        return res;
    }

    private void setDefaultHead(RankingListResVO rankingListResVO, String imageUrl) {


        if (StringUtils.isNotBlank(imageUrl)) {
            rankingListResVO.setImageUrl(imageUrl);
        } else {
            rankingListResVO.setImageUrl(defaultHead);
        }
    }

    /**
     * 设置用户名
     *
     * @param req
     * @param userPo
     */
    private void setRankName(RankingListResVO req, UserPO userPo) {
        try {
            if (Objects.nonNull(userPo)) {
                if (StringUtils.isNotBlank(userPo.getNickName())) {
                    req.setName(userPo.getNickName());
                } else if (StringUtils.isNotBlank(userPo.getName())) {
                    req.setName(userPo.getName());
                }
            }

        } catch (Exception e) {
            log.error(":>>> 设置排行榜名字错误:{}", e);
        }
    }

    /**
     * 获取用户周排行榜
     *
     * @param req
     * @param userPO
     * @param taskInfo
     * @return
     */
    private RankingListResVO getUserWeekRankList(RankingListQueryVO req, UserPO userPO, ActivityTaskInfo taskInfo) {
        RankingListResVO rankingListResVO = new RankingListResVO();
        try {
            req.setPageSize(5);
            Query query = new Query();
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskId").is(req.getTaskId()));
            log.info(":>>> 活动ID:{},任务ID:{}", req.getActivityId(), req.getTaskId());
            Date startWeekTime = TimeUtils.getBeginDayOfWeek();
            Date endWeekTime = TimeUtils.getEndDayOfWeek();
            Criteria criteria = new Criteria().andOperator(Criteria.where("weekTime").gte(TimeUtils.dateToISODate(startWeekTime)), Criteria.where("weekTime").lte(TimeUtils.dateToISODate(endWeekTime)));
            query.addCriteria(criteria);
            // 设置省查询
            this.setRankListProvince(query, req.getActivityId(), req.getProvince(), req.getUserPO());
            Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
            query.with(sort);
            query.limit(req.getPageSize());

            Long count = mongoTemplate.count(query, UserWeekActivityTaskRanking.class);
            PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());

            List<UserWeekActivityTaskRanking> rankings = mongoTemplate.find(query.with(pageRequest), UserWeekActivityTaskRanking.class);
            if (CollectionUtils.isEmpty(rankings)) {
                rankings = new ArrayList<>();
            }
            ActivityInfo activityInfo = cacheActivityService.findById(req.getActivityId());
            List<RankingList> rankingLists = new ArrayList<>();
            boolean in = false;
            int userOrder = 1001;
            int order = 1;
            int orderNN = (req.getPage() - 1) * req.getPageSize() + 1;
            List<String> userIds = new ArrayList<>();
            for (UserWeekActivityTaskRanking d : rankings) {
                if (StringUtils.isNotBlank(d.getUserId())) {
                    userIds.add(d.getUserId());
                }
            }
            HashMap<String, UserPO> userPOHashMap = visitorUserService.getByUserIds(userIds);
            for (UserWeekActivityTaskRanking d : rankings) {
                if (d.getUserId().equals(req.getUserId())) {
                    in = true;
                    userOrder = order;
                }
                RankingList rankingList = new RankingList();

                UserPO userPO1 = userPOHashMap.get(d.getUserId());
                this.setNickNameAndImage(userPO1, rankingList);
                rankingList.setQuantity(d.getQuantity());
                rankingList.setOrderNo(orderNN);
                rankingLists.add(rankingList);
                orderNN++;
                order++;
                if (StringUtils.isNotBlank(d.getUserId())) {
                    userIds.add(d.getUserId());
                }
                rankingList.setRank(activityInfo.getRewardValueUnitDesc());
            }
            rankingListResVO.setDatas(rankingLists);
            rankingListResVO.setInRanking(in);
            Query queryU = new Query();
            queryU.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("taskId").is(req.getTaskId()).and("userId").is(req.getUserId()));
            Criteria criteriaU = new Criteria().andOperator(Criteria.where("weekTime").gte(TimeUtils.dateToISODate(startWeekTime)), Criteria.where("weekTime").lte(TimeUtils.dateToISODate(endWeekTime)));
            queryU.addCriteria(criteriaU);
            UserWeekActivityTaskRanking day = mongoTemplate.findOne(queryU, UserWeekActivityTaskRanking.class);
            if (Objects.isNull(day)) {
                rankingListResVO.setOrderNo(0);
                rankingListResVO.setQuantity(0.0D);
            } else {
                rankingListResVO.setOrderNo(userOrder);
                rankingListResVO.setQuantity(day.getQuantity());
            }
            this.setRankName(rankingListResVO, userPO);
            this.setDefaultHead(rankingListResVO, req.getUserPO().getAvatarUrl());
            rankingListResVO.setDetail(taskInfo.getRankingListContent());
            rankingListResVO.setPage(req.getPage());
            rankingListResVO.setPageSize(req.getPageSize());
            rankingListResVO.setTotalPages(count.intValue() / req.getPageSize() + 1);
        } catch (Exception e) {
            log.error(":>>> 获取排行榜错误:{}", e);
        }

        return rankingListResVO;
    }


    /**
     * 获取承办单位排行榜
     *
     * @param req
     * @param
     * @param taskInfo
     * @return
     */
    private RankingListResVO getOrgAllRankList(RankingListQueryVO req, ActivityTaskInfo taskInfo) {
        RankingListResVO rankingListResVO = new RankingListResVO();
        Long currentTime = System.currentTimeMillis();
        try {
            if (Objects.isNull(req.getPageSize())) {
                req.setPageSize(10);
            }
            Query query = new Query();
            query.addCriteria(Criteria.where("taskId").is(req.getTaskId()).and("activityId").is(req.getActivityId()));
            query.addCriteria(Criteria.where("status").ne(2));
            log.info(":>>> 活动ID:{},任务ID:{}", req.getActivityId(), req.getTaskId());
            // 设置省查询
            String province = this.setRankListProvince(query, req.getActivityId(), req.getProvince(), req.getUserPO());
            Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
            query.with(sort);
            query.limit(req.getPageSize());
            Long startCount = System.currentTimeMillis();
            Long count = this.getOrgRankingCount(req.getActivityId(), req.getTaskId());

            if (Objects.isNull(count) || count == 0) {
                count = mongoTemplate.getCollection(mongoTemplate.getCollectionName(OrganizerRankingList.class)).countDocuments(query.getQueryObject());
                log.info(":>>> 查询承办单位:{} 总数量耗时:{} 毫秒", req.getActivityId(), System.currentTimeMillis() - startCount);
                if (Objects.nonNull(count)) {
                    this.setOrgRankingCount(req.getActivityId(), req.getTaskId(), count);
                }
            }
            if (taskInfo.getRangNum() < count.intValue()) {
                count = Long.valueOf(taskInfo.getRangNum() + "");
            }
            Integer totalPages = 0;
            if (count.intValue() == 0) {
                totalPages = 0;
            } else {
                if (count.intValue() % req.getPageSize() == 0) {
                    totalPages = count.intValue() / req.getPageSize();
                } else {
                    totalPages = count.intValue() / req.getPageSize() + 1;
                }
            }
            log.info(":>>> 用户排行榜数量:{},总页数:{},每页大小:{},当前页:{}", count, totalPages, req.getPageSize(), req.getPage());
            PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
            List<OrganizerRankingList> rankings = null;
            if (totalPages < req.getPage()) {
                rankings = new ArrayList<>();
                log.info(":>>> 排行榜总页数:{} 是最后一页:{}", totalPages, req.getPage());
            } else {
                if (Objects.isNull(rankings) || CollectionUtils.isEmpty(rankings)) {
                    if (req.getPage() == totalPages) {
                        int limit = count.intValue() - (req.getPage() - 1) * req.getPageSize();
                        log.info("当前页面:{},是最后一页:{},限制大小", req.getPage(), totalPages, limit);
                        query.limit(limit);
                        pageRequest = PageRequest.of(req.getPage() - 1, limit);
                    }
                    query.skip((req.getPage() - 1) * req.getPageSize());
                    Long startPage = System.currentTimeMillis();
                    MongoCursor iterable = mongoTemplate.getCollection(mongoTemplate.getCollectionName(OrganizerRankingList.class)).find(query.getQueryObject()).limit(req.getPageSize()).skip((req.getPage() - 1) * req.getPageSize()).noCursorTimeout(true).sort(query.getSortObject()).batchSize(req.getPageSize()).iterator();
                    log.info(":>>> 活动:{} 游标耗时:{} 毫秒", req.getActivityId(), System.currentTimeMillis() - startPage);
                    if (Objects.isNull(rankings)) {
                        rankings = new ArrayList<>();
                    }
                    RankListDomain u = null;
                    Document o = null;
                    String toJson;
                    OrganizerRankingList r = null;
                    while (iterable.hasNext()) {
                        o = (Document) iterable.next();
                        if (Objects.nonNull(o)) {
                            r = new OrganizerRankingList();
                            r.setName(o.getString("name"));
                            r.setImageUrl(o.getString("imageUrl"));
                            r.setQuantity(o.getDouble("quantity"));
                            r.setUserId(o.getString("userId"));
                            r.setOrganizerId(o.getString("organizerId"));
                            rankings.add(r);
                        }
                    }
                    if (Objects.isNull(rankings)) {
                        rankings = new ArrayList<>();
                    }
                    rankService.setOrganizerRankListCache(req.getTaskId(), province, req.getPage(), rankings);
                }
                if (CollectionUtils.isEmpty(rankings)) {
                    rankings = new ArrayList<>();
                }
            }
            List<RankingList> rankingLists = new ArrayList<>();
            boolean in = false;
            int order = 1;
            int orderNN = (req.getPage() - 1) * req.getPageSize();
            List<String> orgIds = new ArrayList<>();
            for (OrganizerRankingList d : rankings) {
                if (StringUtils.isNotBlank(d.getOrganizerId())) {
                    orgIds.add(d.getOrganizerId());
                }
            }
            HashMap<String, ActivityOrganizerInfo> orgMap = activityOrganizerInfoService.findByIds(orgIds);
            for (OrganizerRankingList d : rankings) {
                if (StringUtils.isNotBlank(req.getOrganizerId()) && req.getOrganizerId().equals(d.getOrganizerId())) {
                    in = true;
                }
                ActivityOrganizerInfo organizerInfo = orgMap.get(d.getOrganizerId());
                RankingList rankingList = new RankingList();
                if (Objects.nonNull(organizerInfo)) {
                    rankingList.setImageUrl(organizerInfo.getLogoImageUrl());
                    rankingList.setName(organizerInfo.getOrgName());
                } else {
                    rankingList.setImageUrl(d.getImageUrl());
                    rankingList.setName(d.getName());
                }

                if (Objects.nonNull(d.getQuantity())) {
                    BigDecimal b = new BigDecimal(d.getQuantity());
                    Double q = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                    rankingList.setQuantity(q);
                }
                rankingList.setRankOrganizer();
                rankingList.setOrderNo(order + orderNN);
                rankingList.setUniversityId(d.getUniversityId());
                rankingList.setUniversityName(d.getUniversityName());
                rankingLists.add(rankingList);
                order++;
            }
            rankingListResVO.setDatas(rankingLists);
            rankingListResVO.setInRanking(in);
            rankingListResVO.setDetail(taskInfo.getRankingListContent());
            rankingListResVO.setPage(req.getPage());
            rankingListResVO.setPageSize(req.getPageSize());
            Integer orderOrg = organizerRankingService.getOrgOrder(req.getActivityId(), req.getOrganizerId());
            rankingListResVO.setOrderNo(orderOrg);
            rankingListResVO.setTotalPages(count.intValue() / req.getPageSize() + 1);
        } catch (Exception e) {
            log.error(":>>> 获取承办单位排行榜错误:{}", e);
        }
        log.info(":>>> 获取活动:{} 承办排行榜耗时:{} 毫秒", taskInfo.getActivityId(), (System.currentTimeMillis() - currentTime));
        return rankingListResVO;
    }

    private void setNickNameAndImage(UserPO userPO1, RankingList d) {
//        log.info(":>>> 开始设置头像:{},昵称:{}", d.getImageUrl(), d.getName());
        if (StringUtils.isBlank(d.getImageUrl())) {
            if (Objects.nonNull(userPO1)) {
                if (StringUtils.isNotBlank(userPO1.getAvatarUrl())) {
                    d.setImageUrl(userPO1.getAvatarUrl());
                } else {
                    d.setImageUrl(com.youlu.campus.base.base.Constants.defaultHead);
                }

            }

        }
        if (StringUtils.isBlank(d.getName())) {
            if (Objects.nonNull(userPO1)) {
                if (StringUtils.isNotBlank(userPO1.getNickName())) {
                    d.setName(userPO1.getNickName());
                } else {
                    if (StringUtils.isNotBlank(userPO1.getName())) {
                        if (userPO1.getName().length() >= 2) {
                            String s = userPO1.getName().substring(1);
                            d.setName(s);
                        } else {
                            d.setName(userPO1.getName());
                        }

                    }

                }

            }
        }
    }


    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        java.security.MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    public void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            fileName = new String(fileName.getBytes());
            response.reset();
            response.setContentType("application/msexcel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Cache-Control", "no-cache");
        } catch (Exception ex) {
            log.error(":>>> setResponseHeader error:{}", ex);
        }
    }

    private void setActivityUserInviteExcelTitle(HSSFWorkbook workbook, HSSFSheet sheet) {
        HSSFRow row = sheet.createRow(0);
        //设置列宽，setColumnWidth的第二个参数要乘以256，这个参数的单位是1/256个字符宽度
        sheet.setColumnWidth(0, 10 * 256);
        sheet.setColumnWidth(1, 20 * 256);
        sheet.setColumnWidth(2, 20 * 256);
        sheet.setColumnWidth(3, 20 * 256);

        //设置为居中加粗
        HSSFCellStyle style = workbook.createCellStyle();
        HSSFFont font = workbook.createFont();
        style.setFont(font);

        HSSFCell cell;
        cell = row.createCell(0);
        cell.setCellValue("姓名");
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue("电话");
        cell.setCellStyle(style);

        cell = row.createCell(2);
        cell.setCellValue("报名时间");
        cell.setCellStyle(style);

        cell = row.createCell(3);
        cell.setCellValue("学校");
        cell.setCellStyle(style);
        cell = row.createCell(4);
        cell.setCellValue("答题分数");
        cell.setCellStyle(style);

        cell = row.createCell(5);
        cell.setCellValue("是否通过");
        cell.setCellStyle(style);

    }

    private void setAllUserExcelTitle(HSSFWorkbook workbook, HSSFSheet sheet) {
        HSSFRow row = sheet.createRow(0);
        //设置列宽，setColumnWidth的第二个参数要乘以256，这个参数的单位是1/256个字符宽度
        sheet.setColumnWidth(0, 10 * 256);
        sheet.setColumnWidth(1, 20 * 256);
        sheet.setColumnWidth(2, 20 * 256);
        sheet.setColumnWidth(3, 100 * 256);

        //设置为居中加粗
        HSSFCellStyle style = workbook.createCellStyle();
        HSSFFont font = workbook.createFont();
        style.setFont(font);

        HSSFCell cell;
        cell = row.createCell(0);
        cell.setCellValue("姓名");
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue("性别");
        cell.setCellStyle(style);

        cell = row.createCell(2);
        cell.setCellValue("学校名称");
        cell.setCellStyle(style);

        cell = row.createCell(3);
        cell.setCellValue("省");
        cell.setCellStyle(style);

        cell = row.createCell(4);
        cell.setCellValue("参与活动次数");
        cell.setCellStyle(style);

    }

    private String getCellStr(Cell cell) {
        if (Objects.isNull(cell)) {
            return "";
        }
        switch (cell.getCellTypeEnum()) {
            case NUMERIC:
                Double v = cell.getNumericCellValue();
                if (Objects.nonNull(v)) {
                    return v.intValue() + "";
                }
                break;
            case STRING:
                return cell.getStringCellValue();
            case BLANK:
                return "";
            default:
                break;
        }
        return "";
    }

    /**
     * 设置任务完成情况明细
     *
     * @param taskInfo
     * @return
     */
    @Override
    public ActivityTaskDataDomain getTaskDataDomain(ActivityTaskInfo taskInfo, String userId, ActivityRewardRule rule, List<String> uid) {
        if (Objects.isNull(rule)) {
            log.error(":>>> 任务规则为空:{},{}", userId, taskInfo.getId());
            ActivityTaskDataDomain res = new ActivityTaskDataDomain();
            res.setCaName("暂无证书");
            return res;
        }
        ActivityInfo activityInfo = this.findOne(taskInfo.getActivityId());
        if (Objects.isNull(taskInfo) || Objects.isNull(activityInfo)) {
            log.error(":>>> 任务或活动不存在");
            return null;
        }
        // 设置承办单位任务量
        RankingListResVO res = null;
        switch (taskInfo.getTaskBizType()) {
            case INVITE:
                res = new RankingListResVO();
                res.setInRanking(Boolean.FALSE);
                res.setOrderNo(0);
                res.setQuantity(rule.getToMatchValue());
                res.setOrderNo(0);
                //res = getUserOrder(userId, taskInfo);
                break;
            case ORGANIZER:
                ActivityOrganizerInfo activityOrganizerInfo = activityOrganizerInfoService.find(taskInfo.getActivityId(), userId);
                if (Objects.nonNull(activityOrganizerInfo)) {
                    res = getOrgRankOrder(activityOrganizerInfo.getId(), taskInfo);
                }
                break;
        }
        ActivityTaskDataDomain d = new ActivityTaskDataDomain();
        d.setBizId(taskInfo.getId());
        d.setBizType(taskInfo.getTaskBizType());
        if (Objects.nonNull(rule)) {
            d.setBoon(rule.getBoon());
        }
        if (Objects.nonNull(res)) {
            if (res.getInRanking()) {
                d.setOrderNo(res.getOrderNo() + "");
                d.setOrderStr("第" + res.getOrderNo() + "名");
                d.setQ(res.getQuantity());
                String unit = taskInfo.getUnit();
                if (StringUtils.isBlank(unit)) {
                    d.setQStr(res.getQuantity().intValue() + "人");
                } else {
                    if ("-".equals(unit)) {
                        d.setQStr(res.getQuantity().intValue() + "");
                    } else {
                        d.setQStr(res.getQuantity().intValue() + unit);
                    }

                }

            } else {
                d.setOrderNo(d.getOrderNo());
                d.setOrderStr("暂未入榜");
                d.setQ(res.getQuantity());
                String unit = taskInfo.getUnit();
                if (StringUtils.isBlank(unit)) {
                    d.setQStr(res.getQuantity() + "人");
                } else {
                    if ("-".equals(unit)) {
                        d.setQStr(res.getQuantity().intValue() + "");
                    } else {
                        if (Objects.nonNull(res.getQuantity())) {
                            d.setQStr(res.getQuantity().intValue() + unit);
                        } else {
                            d.setQStr(0 + unit);
                        }

                    }
                }
            }
        } else {
            res = new RankingListResVO();
            res.setQuantity(0.0D);
            d.setOrderNo("0");
            d.setOrderStr("暂未入榜");
            d.setQ(0.0D);
            d.setQStr("暂未入榜");
        }
        if (Objects.nonNull(res) && StringUtils.isNotBlank(res.getRankValue())) {
            d.setOrderStr(res.getRankValue());
        }
        // 设置这三个参数
        if (Objects.nonNull(rule)) {
            if (Boolean.TRUE.equals(rule.getReplaced())) {
                if (StringUtils.isNotBlank(rule.getTips()) && Objects.nonNull(res.getQuantity()) && Objects.nonNull(rule.getNextCaQ())) {

                    switch (taskInfo.getTaskBizType()) {

                        case ORGANIZER:
                            if (StringUtils.isNotBlank(rule.getNextCaName())) {

                                if (Objects.nonNull(rule.getNextCaQ()) && Objects.nonNull(res.getQuantity())) {
                                    Double nextCaQ = Double.valueOf("" + rule.getNextCaQ());
                                    Double q = Double.valueOf("" + res.getQuantity());
                                    if (nextCaQ.compareTo(q) == -1) {
                                        log.error(":>>> 严重警告,nextCaQ:{} < q:{}", nextCaQ, q);
                                        d.setTips(taskInfo.getDefaultTips());
                                    } else {
                                        Double i = nextCaQ - q;
                                        try {
                                            d.setRateTips(String.format(rule.getTips(), i.intValue(), rule.getNextCaName()));
                                        } catch (Exception e) {
                                            log.error(":>>> 替换提示语出错:{}", e);
                                        }

                                    }
                                }

                            } else {
                                d.setRateTips("加油,再接再厉!");
                            }
                            break;
                        case INVITE:
                            if (StringUtils.isNotBlank(rule.getCaName()) && StringUtils.isNotBlank(rule.getTips())) {
                                if (Objects.nonNull(rule.getNextCaQ()) && Objects.nonNull(res.getQuantity())) {
                                    Double nextCaQ = Double.valueOf("" + rule.getNextCaQ());
                                    Double q = Double.valueOf("" + res.getQuantity());
                                    if (nextCaQ.compareTo(q) == -1) {
                                        log.error(":>>> 严重警告,nextCaQ:{} < q:{}", nextCaQ, q);
                                        d.setTips(taskInfo.getDefaultTips());
                                    } else {
                                        Double a = nextCaQ - q;
                                        Double b = a;
                                        if (!"qq".equals(rule.getPlatform())) {
                                            if ("invited-num".equals(taskInfo.getProgressBarType())) {
                                                b = Math.ceil(a / (taskInfo.getRatio() == null ? 1 : taskInfo.getRatio()));
                                            }
                                        }
                                        try {
                                            d.setRateTips(String.format(rule.getTips(), b.intValue(), rule.getNextCaName()));

                                        } catch (Exception e) {
                                            log.error(":>>> 替换邀请提示语错误:{}", e);
                                        }

                                    }
                                }
                            } else {
                                d.setRateTips("加油,再接再厉!");
                            }
                            break;
                        default:
                            break;
                    }

                } else {
                    d.setRateTips("加油,再接再厉!");
                }
            } else {
                d.setRateTips(rule.getTips());
            }
            if (Objects.nonNull(rule.getOrderNo()) && Objects.nonNull(rule.getOrderTotal())) {
                d.setRate(rule.getOrderNo() / rule.getOrderTotal());
            } else {
                d.setRate(0.1D);
            }
            d.setCaName(rule.getCaName());
            d.setOriginCaName(rule.getCaName());
        } else {
            d.setCaName("暂无证书");
            d.setOriginCaName("暂无证书");
            d.setRate(0.0D);
            d.setRateTips("加油呀");
        }
        d.setTips(taskInfo.getH5Tips());
        d.setHasGiftTips(taskInfo.getHasGiftTips());
        d.setGiftTips(taskInfo.getGiftTips());
        d.setBackGroundImageUrl(taskInfo.getBackGroundImageUrl());
        Query queryInvite = new Query().addCriteria(Criteria.where("invitedByUserId").in(uid).and("taskId").is(taskInfo.getId()).and("joinStatus").is(Boolean.TRUE));
        Long count = mongoTemplate.count(queryInvite, UserInviteRecord.class);
        d.setInviteNum(count == null ? 0 : count.intValue());
        return d;


    }

    /**
     * 更新用户总榜单
     *
     * @param userPO
     * @param taskInfo
     * @param optType,0:累加,1:替换
     */
    @Async
    @Override
    public void updateUserTaskAllRanking(final UserPO userPO, UserParticipateActivityTaskInfo taskInfo, final Integer optType) {
        log.info(":>>> 开始更新用户榜单用户:{},任务数据:{},操作类型:{}", JSON.toJSONString(userPO), JSON.toJSONString(taskInfo), optType);
        if (Objects.isNull(userPO) || Objects.isNull(taskInfo) || Objects.isNull(optType)) {
            log.error(":>>> 更新用户排行榜参数错误:用户、任务量、操作类型为空");
            return;
        }
        ActivityTaskInfo activityTaskInfo = this.findActivityTaskInfo(taskInfo.getActivityId(), TaskBizType.INVITE);
        //重置 贡献值
        activityTaskInfo.setPoints(taskInfo.getQuantity());
        //更新用户 贡献值
        userActivityTaskRankingService.saveQuantity(userPO, activityTaskInfo, TaskBizType.INVITE);
    }

    @Override
    public Double getTaskQuantity(String activityId, String type, String taskId, List<String> uids) {
        log.info(":>>> 开始获取用户:{} 活动:{} 类型:{},用户:{} 贡献值", activityId, type, JSON.toJSONString(uids));
        Long currentTime = System.currentTimeMillis();
        Double q = 0.0D;
        if (Arrays.asList(ACTIVITY__V2).contains(type)) {
            Query query = new Query().addCriteria(Criteria.where("userId").in(uids).and("activityId").is(activityId));
            List<UserActivityPointRanking> rankings = mongoTemplate.find(query, UserActivityPointRanking.class);
            if (!CollectionUtils.isEmpty(rankings)) {
                for (UserActivityPointRanking ranking : rankings) {
                    if (Objects.nonNull(ranking.getQuantity())) {
                        q = q + ranking.getQuantity();
                    }
                }
            }
            return q;
        } else {
            q = this.getTaskQuantityByUids(activityId, taskId, uids);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").in(uids).and("activityId").is(activityId));
        UserParticipateActivityInfo user = this.mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.nonNull(user) && user.getImportQuantityAdd()) {//如果存在无需第二次重新计算
            return q;
        }
        List<UserActivityTaskRankingAttach> datas = userActivityTaskRankingAttachService.find(uids, activityId, taskId);
        if (!CollectionUtils.isEmpty(datas)) {
            for (UserActivityTaskRankingAttach attach : datas) {
                if (Objects.nonNull(attach.getQuantity())) {
                    q = q + attach.getQuantity();
                }
            }
        }
        log.info(":>>> 耗时:{},结束获取活动:{} 类型:{},用户:{} 贡献值", (System.currentTimeMillis() - currentTime), activityId, type, JSON.toJSONString(uids));
        return q;
    }

    @Override
    public List<UserParticipateActivityInfo> getUserQuantity(String activityId, String type, String taskId, List<String> uids) {
        log.info(":>>> 开始获取用户活动:{} 类型:{},用户:{} 贡献值", activityId, type);
        if (Arrays.asList(ACTIVITY__V2).contains(type)) {
            Query query = new Query().addCriteria(Criteria.where("userId").in(uids).and("activityId").is(activityId));
            List<UserActivityPointRanking> rankingList = mongoTemplate.find(query, UserActivityPointRanking.class);
            if (!CollectionUtils.isEmpty(rankingList)) {
                return rankingList.stream().map(userActivityPointRanking -> {
                    UserParticipateActivityInfo userParticipateActivityInfo = new UserParticipateActivityInfo();
                    userParticipateActivityInfo.setUserId(userActivityPointRanking.getUserId());
                    userParticipateActivityInfo.setActivityId(activityId);
                    userParticipateActivityInfo.setQuantity(userActivityPointRanking.getQuantity());
                    return userParticipateActivityInfo;
                }).collect(Collectors.toList());
            }
        }
        List<UserParticipateActivityInfo> result = new LinkedList<>();
        // 查询用户
        List<UserActivityTaskRanking> userTaskRankingList = userActivityTaskRankingService.findByActivityIdAndTaskIdAndUserIdIn(activityId, taskId, uids);
        if (!CollectionUtils.isEmpty(userTaskRankingList)) {
            userTaskRankingList.stream().forEach(userActivityTaskRanking -> {
                UserParticipateActivityInfo userParticipateActivityInfo = new UserParticipateActivityInfo();
                userParticipateActivityInfo.setUserId(userActivityTaskRanking.getUserId());
                userParticipateActivityInfo.setActivityId(activityId);
                List<UserActivityTaskRankingAttach> datas = userActivityTaskRankingAttachService.findAll(userActivityTaskRanking.getUserId(), activityId);
                Double q = userActivityTaskRanking.getQuantity();
                if (Objects.nonNull(datas)) {
                    for (UserActivityTaskRankingAttach ua : datas) {
                        if (Objects.nonNull(ua.getQuantity())) {
                            q = q + ua.getQuantity();
                        }
                    }
                }
                userParticipateActivityInfo.setQuantity(q);
                result.add(userParticipateActivityInfo);
            });
        }
        return result;
    }

    @Override
    public Double getTaskQuantityByUids(String activityId, String taskId, List<String> uids) {
        Date date = new Date();
        log.info(":>>> 开始获取活动:{},任务:{},uids:{} 贡献值", activityId, taskId, JSON.toJSONString(uids));
        Double q = 0.0D;
        if (CollectionUtils.isEmpty(uids)) {
            log.error(":>>> 查找taskId:{}--activityId:{}  用户ID结合为空", taskId, activityId);
            return diTanQ(q, activityId, taskId, date, uids);
        }

        // 查询用户
        List<UserActivityTaskRanking> datas = userActivityTaskRankingService.findByActivityIdAndTaskIdAndUserIdIn(activityId, taskId, uids);
        if (CollectionUtils.isEmpty(datas)) {
            log.error(":>>> 活动:{},任务:{},uids:{} 贡献值集合为空,贡献值为0", activityId, taskId, JSON.toJSONString(uids));
            return diTanQ(q, activityId, taskId, date, uids);
        }

        for (UserActivityTaskRanking userActivityTaskRanking : datas) {
            if (Objects.nonNull(userActivityTaskRanking.getQuantity())) {
                q = q + userActivityTaskRanking.getQuantity();
            }
        }
        log.info(":<<< 结束获取活动:{},任务:{},手机号:{} 贡献值:{},耗时:{} 豪秒", activityId, taskId, JSON.toJSONString(uids), q, (new Date().getTime() - date.getTime()));
        // 高校节能低碳志愿行动,分享任务
        return diTanQ(q, activityId, taskId, date, uids);

    }

    // 最好50个贡献值
    private Double diTanQ(Double q, String activityId, String taskId, Date date, List<String> uids) {
        if ("6119dfde60d5e87e7e3b0b19".equals(activityId) && "6119dfdf60d5e87e7e3b0b1a".equals(taskId)) {
            if (Objects.isNull(q)) {
                q = 60.0D;
            }
            int t = 0;
            // 2021-09-11 00:00:59 :1631289659000 不加贡献值
            if (date.after(new Date(1631289659000L))) {
                t = TimeUtils.getDiffDays(new Date(1631030400000L), new Date(1631289659000L));
            } else {
                t = TimeUtils.getDiffDays(new Date(1631030400000L), date);
            }
            q = q + 10.0D * t + 20 + 20 + 20;
            log.info(":>>> 用户:{},活动:{},为高校节能低碳志愿行动，所有人贡献值+60", JSON.toJSONString(uids), activityId, q - 15, q);
            return q;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").in(uids).and("activityId").is(activityId));
        UserParticipateActivityInfo user = this.mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.nonNull(user) && user.getImportQuantityAdd()) {
            return q;
        }
        List<UserActivityTaskRankingAttach> datas = userActivityTaskRankingAttachService.find(uids, activityId, taskId);
        if (!CollectionUtils.isEmpty(datas)) {
            for (UserActivityTaskRankingAttach u : datas) {
                if (Objects.nonNull(u.getQuantity())) {
                    q = q + u.getQuantity();
                }
            }
        }
        return q;
    }

    private void updateInviteRank(UserPO invitedByUser, UserPO invitedToUser, UserInviteRecord record, String activityId, String taskId) {
        ActivityInfo activityInfo = this.findOne(record.getActivityId());
        ActivityTaskRule rule = activityTaskRuleService.find(record.getActivityId(), TaskBizType.INVITE.name());
        if (Objects.nonNull(record) && StringUtils.isNotBlank(record.getInvitedByUserId())) {
            if (!("qq-mini-plus-noncontest".equals(activityInfo.getType()) || "qq-mini-plus".equals(activityInfo.getType()) || "h5++".equals(activityInfo.getType()) || "qq-mini-zhongqing-contest".equals(activityInfo.getType()))) {
                this.updateTaskQuantity(record.getInvitedByUserId(), activityId, taskId, TaskBizType.INVITE, 1.0D);
                ActivityTaskInfo taskInfo = this.getTaskInfo(activityId, TaskBizType.INVITE);
                //更新用户 贡献值
                taskInfo.setPoints(activityInfo.getRatio());
                userActivityTaskRankingService.saveQuantity(invitedByUser, taskInfo, TaskBizType.INVITE);
                // 更新周榜单
                //this.updateUserTaskWeekRanking(invitedByUser, userParticipateActivityTaskInfo, 0);
            } else {
                ActivityTaskInfo taskInfo = activityTaskService.findOne(taskId);
                String desc = "分享用户";
                //
                boolean limitInvite = false;
                UserParticipateActivityInfo up = userUpInfoService.findByUserIdActivityId(invitedByUser.getId(), activityId);
                log.info(":>>> 活动:{},邀请人:{} 报名时间:{}", activityId, invitedByUser.getId(), up == null ? null : up.getSignUpTime());
                if (Objects.nonNull(up) && Objects.nonNull(up.getSignUpTime()) && Objects.nonNull(taskInfo.getInviteLimit())) {
                    if ((new Date().getTime() - up.getSignUpTime().getTime()) <= taskInfo.getInviteLimit() * 1000) {
                        limitInvite = true;
                    }
                }
                if (limitInvite && Boolean.TRUE.equals(taskInfo.getHasInviteLimit())) {
                    rule.setPoints(taskInfo.getInviteLimitQuantity());
                    desc = "限时分享";
                } else {
                    rule.setPoints(taskInfo.getPoints());
                }
                UserActivityPointDetail detail = new UserActivityPointDetail();
                detail.setActivityId(record.getActivityId());
                detail.setUserId(record.getInvitedByUserId());
                UserPO userPO = visitorUserService.getUser(record.getInvitedByUserId());
                detail.setUserPO(userPO);
                detail.setPoints(rule.getPoints().intValue());
                detail.setAction("add");
                detail.setBizDesc(desc);
                detail.setBizType("invite");
                userActivityPointDetailService.create(detail);
                // 更新省排行榜
                userActivityPointRankingProvinceService.updatePoint(userPO, record.getActivityId(), rule.getPoints().intValue());
            }

        }
    }

    /**
     * 签到更新用户榜单
     *
     * @param userPO
     * @param activityId
     */
    @Override
    public void updateRank(UserPO userPO, String activityId, Double ratio) {
        try {
            ActivityTaskInfo taskInfo = this.getTaskInfo(activityId, TaskBizType.INVITE);
            if (taskInfo == null) {
                log.error(":>>> 获取任务信息错误:{}", activityId);
                return;
            }
            final String userId = userPO.getId();
            this.updateTaskQuantity(userId, activityId, taskInfo.getId(), TaskBizType.INVITE, 1.0D);
            //更新用户 贡献值
            taskInfo.setPoints(ratio);//重置 贡献值
            userActivityTaskRankingService.saveQuantity(userPO, taskInfo, TaskBizType.LEARNING);
            // 更新高校参与人数榜单 (TODO疑惑: 签到要更新吗?不用吧,暂时注释掉)
            // this.updateUniversityTaskAllRanking(userPO, userParticipateActivityTaskInfo, 0);
        } catch (Exception e) {
            log.error(":>>> 更新用户榜单错误:{}", e);
        }

    }

    @Override
    public UserParticipateActivityInfo getUserParticipateActivityInfo(String userId, String activityId) {
        log.info(":>>> 开始获取用户:{},活动:{} 报名信息", userId, activityId);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(activityId)) {
            log.error(":>>> 活动ID或用户ID为空");
            throw new BusinessException("参数错误");
        }
        Query queryP = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        UserParticipateActivityInfo participateActivityInfo = mongoTemplate.findOne(queryP, UserParticipateActivityInfo.class);
        return participateActivityInfo;
    }

    @Override
    public UserQaInfo getUserQa(String userId, String activityId) {
        log.info(":>>> 开始获取用户答题记录:{},{}", userId, activityId);
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("passed").is(Boolean.TRUE));
//        query.with(new Sort(Sort.Direction.DESC, "no"));
        Sort sort = Sort.by(Sort.Direction.DESC, "no");
        query.with(sort);
        UserQaInfo userQaInfo = mongoTemplate.findOne(query, UserQaInfo.class);
        log.info(":>>> 用户:{},活动:{}, 通过的答题记录:{}", userId, activityId, JSON.toJSONString(userQaInfo));
        return userQaInfo;
    }

    @Override
    public List<UserQaInfo> getUserQas(String userId, String activityId) {
        log.info(":>>> 开始获取用户答题记录:{},{}", userId, activityId);
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("passed").is(Boolean.TRUE));
//        query.with(new Sort(Sort.Direction.DESC, "no"));
        Sort sort = Sort.by(Sort.Direction.DESC, "no");
        query.with(sort);
        List<UserQaInfo> userQaInfos = mongoTemplate.find(query, UserQaInfo.class);
        log.info(":>>> 用户:{},活动:{}, 通过的答题记录:{}", userId, activityId, JSON.toJSONString(userQaInfos));
        return userQaInfos;
    }

    private RankingListResVO getOrgRankOrder(String organizerId, ActivityTaskInfo taskInfo) {
        RankingListResVO rankingListResVO = new RankingListResVO();
        try {
            Query query = new Query();
            query.addCriteria(Criteria.where("activityId").is(taskInfo.getActivityId()).and("taskId").is(taskInfo.getId()));
            log.info(":>>> 活动ID:{},任务ID:{}", taskInfo.getActivityId(), taskInfo.getId());
//            query.with(new Sort(Sort.Direction.DESC, "quantity"));
            Sort sort = Sort.by(Sort.Direction.DESC, "quantity");
            query.with(sort);
            if (Objects.isNull(taskInfo.getRangNum())) {
                taskInfo.setRangNum(1000);
            }
            query.limit(300);
            List<OrganizerRankingList> rankings = mongoTemplate.find(query, OrganizerRankingList.class);
            if (CollectionUtils.isEmpty(rankings)) {
                rankings = new ArrayList<>();
            }
            boolean in = false;
            int order = 1;
            int uOrder = 0;
            for (OrganizerRankingList d : rankings) {
                log.info(":>>> 机构:{}", d.getOrganizerId());
                if (StringUtils.isNotBlank(organizerId) && organizerId.equals(d.getOrganizerId())) {
                    in = true;
                    uOrder = order;
                }
                order++;
            }
            rankingListResVO.setInRanking(in);
            // 查询用户
            Query queryU = new Query();
            queryU.addCriteria(Criteria.where("organizerId").is(organizerId).and("taskId").is(taskInfo.getId()).and("activityId").is(taskInfo.getActivityId()));
            OrganizerRankingList day = mongoTemplate.findOne(queryU, OrganizerRankingList.class);
            if (Objects.isNull(day)) {
                rankingListResVO.setOrderNo(0);
                rankingListResVO.setQuantity(0.0D);
            } else {
                rankingListResVO.setOrderNo(uOrder);
                rankingListResVO.setQuantity(day.getQuantity());
            }
            rankingListResVO.setInRanking(in);
            if (uOrder == 0) {
                rankingListResVO.setRankValue("未入榜");
            } else {
                rankingListResVO.setRankValue("第" + uOrder + "名");
            }
            rankingListResVO.setDetail(taskInfo.getRankingListContent());
            log.info(":>>> 活动:{} 承办单位名次:{} 结果:{}", taskInfo.getActivityId(), organizerId, JSON.toJSONString(rankingListResVO));
        } catch (Exception e) {
            log.error(":>>> 获取承办单位排行榜错误:{}", e);
        }
        return rankingListResVO;
    }

    private String getUniversityId(String activityId, String userId) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        UserParticipateActivityInfo exist = mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.isNull(exist)) {
            return null;
        }
        return exist.getUniversityId();
    }

    /**
     * 获取申办单位工作量
     *
     * @param activityId
     * @param taskId
     * @param organizerId
     * @return
     */
    private Double getOrgQ(String activityId, String taskId, String organizerId) {
        Query queryU = new Query();
        queryU.addCriteria(Criteria.where("organizerId").is(organizerId).and("taskId").is(taskId).and("activityId").is(activityId));
        OrganizerRankingList day = mongoTemplate.findOne(queryU, OrganizerRankingList.class);
        if (Objects.isNull(day)) {
            return 0.0D;
        } else {
            return day.getQuantity();
        }
    }

    /**
     * 获取申办单位工作量
     *
     * @param activityId
     * @param taskId
     * @param organizerIds
     * @return
     */
    @Override
    public Double getOrgQByOrgIds(String activityId, String taskId, List<String> organizerIds) {
        Query queryU = new Query();
        queryU.addCriteria(Criteria.where("organizerId").in(organizerIds).and("taskId").is(taskId).and("activityId").is(activityId));
        List<OrganizerRankingList> datas = mongoTemplate.find(queryU, OrganizerRankingList.class);
        if (CollectionUtils.isEmpty(datas)) {
            return 0.0D;
        }
        Double q = 0.0D;
        for (OrganizerRankingList data : datas) {
            if (Objects.nonNull(data.getQuantity())) {
                q = q = data.getQuantity();
            }
        }
        return q;
    }

    @Async
    @Override
    public void extSignUpActivity(ActivitySignUpRequest request, UserPO userPO) {
        log.info(":>>> 开始补充报名信息:{},{}", JSON.toJSONString(request), JSON.toJSON(userPO));
        final String activityId = request.getActivityId();
        if (StringUtils.isBlank(activityId)) {
            return;
        }
        try {
            // 默认邀请任务
            ActivityTaskInfo taskInfo = this.findActivityTaskInfo(request.getActivityId(), TaskBizType.INVITE);
            log.info(":.>> 活动:{} 邀请任务:{}", request.getActivityId(), taskInfo == null ? null : taskInfo.getId());
            if (Objects.isNull(taskInfo)) {
                log.error(":>>> 该活动没有配置邀请任务:{}", request.getActivityId());
                throw new BusinessException("该活动没有配置邀请任务");
            }
            //更新邀请状态
            log.info(":>>> 开始查找用户:{},活动:{},任务:{} 被邀请记录", request.getUserId(), request.getActivityId(), taskInfo.getId());
            // 用户被邀请记录
            UserInviteRecord record = this.getInvitedRecord(request.getUserId(), request.getActivityId(), taskInfo.getId());
            UserPO invitedByUser = null;
            if (Objects.nonNull(record)) {
                log.info(":>>> 用户被邀请记录为受邀人:{}--{} ---^^_ 邀请人:{}--{}", record.getInvitedToUserId(), record.getInvitedToUserName(), record.getInvitedByUserId(), record.getInvitedByUserName());
                if (StringUtils.isNotBlank(record.getInvitedByUserId())) {
                    invitedByUser = visitorUserService.getUserUserId(request.getPlatform(), request.getAppId(), record.getInvitedByUserId());
                    if (Objects.nonNull(invitedByUser) && StringUtils.isBlank(invitedByUser.getUniversityId())) {
                        String uniId = getUniversityId(activityId, invitedByUser.getId());
                        invitedByUser.setUniversityId(uniId);
                    }
                    UserPO invitedToUser = visitorUserService.getUserUserId(request.getPlatform(), request.getAppId(), record.getInvitedToUserId());
                    if (Objects.nonNull(invitedToUser)) {
                        if (StringUtils.isBlank(invitedToUser.getUniversityId())) {
                            String uniId = getUniversityId(activityId, invitedToUser.getId());
                            invitedToUser.setUniversityId(uniId);
                        }

                    }
                    if (Objects.nonNull(invitedByUser) && Objects.nonNull(invitedToUser)) {
                        ActivityInfo activityInfo = this.findOne(activityId);
                        if (!"wx-mini-dreambeat-contest".equals(activityInfo.getType())) {
                            this.updateInviteRank(invitedByUser, invitedToUser, record, activityId, taskInfo.getId());
                        }
                        userInviteRecordService.updateInvitedCount(invitedToUser.getId(), activityId);
                        // 写入证书
                        this.generateUserCa(activityId, "", invitedByUser, request.getPlatform());

                        if (!"wx-mini-dreambeat-contest".equals(activityInfo.getType())) {
                            if (Boolean.TRUE.equals(activityInfo.getHasPoint())) {
                                Integer point = pointPlatformConfigService.getPoint("invite");
                                UserPointsDetail detail = new UserPointsDetail();
                                detail.setUserId(invitedByUser.getId());
                                detail.setAction("add");
                                detail.setBizDesc("邀请用户");
                                detail.setBizType("invite");
                                detail.setOptDate(new Date());
                                detail.setPoints(point);
                                detail.setComments("邀请用户" + point + "积分");
                                userPointsService.addPoint(detail);
                                userPointRankingService.updatePoint(invitedByUser, "", point);
                            }
                        }

                    }
                }
            }
        } catch (Exception e) {
            log.error(":>>> 处理补充报名信息:{}", e);
        }

    }

    /**
     * 获取足迹的审核数量
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public ActivityFootPrintDomain getActivityFootPrint(String userId, String activityId, String taskBizType) {
        log.info(":>>> 开始查询活动足迹:{},{}", userId, activityId);
        Long currentTime = System.currentTimeMillis();

        if (StringUtils.isBlank(userId) || StringUtils.isBlank(activityId)) {
            log.error(":>>> 查询活动足迹参数错误");
            throw new BusinessException("查询活动足迹参数错误:ID不能为空");
        }
        ActivityFootPrintDomain res = new ActivityFootPrintDomain();

        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        if (StringUtils.isBlank(taskBizType)) {
            query.addCriteria(Criteria.where("taskBizType").is(null));
        } else {
            query.addCriteria(Criteria.where("taskBizType").is(taskBizType));
        }
        List<UserActivityFootPrint> datas = mongoTemplate.find(query, UserActivityFootPrint.class);
        log.info(":>>> 用户是否有足迹:{},{},{}", userId, activityId, datas == null ? 0 : datas.size());
        if (CollectionUtils.isEmpty(datas)) {
            return res;
        }
        res.setTotalNum(datas.size());
        for (UserActivityFootPrint u : datas) {
            if (Objects.nonNull(u.getStatus()) && u.getStatus().intValue() == 1) {
                res.setPassedNum((res.getPassedNum() == null ? 0 : res.getPassedNum()) + 1);
            }
        }
        log.info(":>>> 结束查询活动足迹:{},{},耗时:{} 毫秒", userId, activityId, (System.currentTimeMillis() - currentTime));
        return res;
    }

    @Async
    @Override
    public void updateActivityJoinNum(String activityId, Integer num, Date date) {
        try {
            DayActivityJoinRecord dayActivityJoinRecord = new DayActivityJoinRecord();
            dayActivityJoinRecord.setActivityId(activityId);
            dayActivityJoinRecord.setNum(num);
            dayActivityJoinRecord.setTime(date);
            activityDataService.createDayActivityJoinRecord(dayActivityJoinRecord);
            HourActivityJoinRecord hourActivityJoinRecord = new HourActivityJoinRecord();
            hourActivityJoinRecord.setActivityId(activityId);
            hourActivityJoinRecord.setNum(num);
            hourActivityJoinRecord.setTime(date);
            activityDataService.createHourActivityJoinRecord(hourActivityJoinRecord);
        } catch (Exception e) {
            log.error(":>>> 更新活动参与人数错误", e);
        }

    }

    /**
     * 设置线下志愿者活动
     *
     * @param activityInfo
     * @param activityRewardRule
     * @param userParticipateActivityInfo
     * @param userId
     */
    private void setOffLine(ActivityInfo activityInfo, ActivityRewardRule activityRewardRule, UserParticipateActivityInfo userParticipateActivityInfo, String userId) {
        log.info(":>>> 活动有线下活动:{}", activityInfo.getId());
        ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityInfo.getId(), TaskBizType.OFF_LINE.name());
        log.info(":>>> 活动有线下活动:{},状态:{},{} ", activityInfo.getId(), userId, JSON.toJSONString(printDomain));
        /**
         * 线下组织活动状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
         */
        ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.OFF_LINE.name());
        if (Objects.isNull(taskRule)) {
            log.error(":>>> 活动:{} 没有没有配置:{} 任务明细", activityInfo.getId(), TaskBizType.OFF_LINE.name());
            throw new BusinessException("活动没有配置线下任务规则明细");
        }
        if (Boolean.TRUE.equals(activityInfo.getOffLineNeedVerify())) {
            if (printDomain.getTotalNum().intValue() == 0) {
                userParticipateActivityInfo.setOffLineStatus(0);
                activityRewardRule.setOffLineStatus(false);
            } else {

                if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                    userParticipateActivityInfo.setOffLineStatus(4);
                    activityRewardRule.setOffLineStatus(true);
                } else {
                    userParticipateActivityInfo.setOffLineStatus(3);
                    activityRewardRule.setOffLineStatus(false);
                }
            }
        } else {
            if (printDomain.getTotalNum().intValue() > 0) {
                userParticipateActivityInfo.setOffLineStatus(3);
                activityRewardRule.setOffLineStatus(true);
            } else {
                userParticipateActivityInfo.setOffLineStatus(0);
                activityRewardRule.setOffLineStatus(false);
            }
        }

    }

    /**
     * 设置志愿者福利
     *
     * @param activityInfo
     * @param activityRewardRule
     * @param userParticipateActivityInfo
     * @param userId
     */
    private void setVolunteerWelfare(ActivityInfo activityInfo, ActivityRewardRule activityRewardRule, UserParticipateActivityInfo userParticipateActivityInfo, String userId) {
        log.info(":>>> 活动有志愿福利:{}", activityInfo.getId());
        if (!Boolean.TRUE.equals(activityInfo.getHasVolunteerWelfare())) {
            userParticipateActivityInfo.setVolunteerWelfareStatus(0);
            activityRewardRule.setVolunteerWelfareStatus(false);
            return;
        }
        ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityInfo.getId(), TaskBizType.WELFARE.name());
        log.info(":>>> 活动志愿福利:{},状态:{},{} ", activityInfo.getId(), userId, JSON.toJSONString(printDomain));
        /**
         * 线下组织活动状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
         */
        ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.WELFARE.name());
        if (Objects.isNull(taskRule)) {
            log.error(":>>> 活动:{} 没有配置:{} 任务明细", activityInfo.getId(), TaskBizType.WELFARE.name());
            throw new BusinessException("活动没有配置志愿福利规则明细");
        }
        if (printDomain.getTotalNum().intValue() == 0) {
            userParticipateActivityInfo.setVolunteerWelfareStatus(0);
            activityRewardRule.setVolunteerWelfareStatus(false);
        } else {
            if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                userParticipateActivityInfo.setVolunteerWelfareStatus(4);
                activityRewardRule.setVolunteerWelfareStatus(true);
            } else {
                userParticipateActivityInfo.setVolunteerWelfareStatus(3);
                activityRewardRule.setVolunteerWelfareStatus(false);
            }
        }
    }

    /**
     * 设置直播任务
     *
     * @param activityInfo
     * @param activityRewardRule
     * @param userParticipateActivityInfo
     * @param userId
     */
    private void setBroadcast(ActivityInfo activityInfo, ActivityRewardRule activityRewardRule, UserParticipateActivityInfo userParticipateActivityInfo, String userId) {
        log.info(":>>> 活动有直播任务:{}", activityInfo.getId());
        if (!Boolean.TRUE.equals(activityInfo.getHasVolunteerWelfare())) {
            userParticipateActivityInfo.setBroadcastStatus(0);
            activityRewardRule.setBroadcastStatus(false);
            log.info(":>>> 该活动没有直播任务:{}", activityInfo.getId());
            return;
        }
        ActivityFootPrintDomain printDomain = getActivityFootPrint(userId, activityInfo.getId(), TaskBizType.BROADCASAT.name());
        log.info(":>>> 活动直播任务:{},状态:{},{} ", activityInfo.getId(), userId, JSON.toJSONString(printDomain));
        /**
         * 直播任务状态,0: 未完成,1:已完成,2:未报名,3:待审核,4:审核通过,5:审核不通过
         */
        ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.BROADCASAT.name());
        if (Objects.isNull(taskRule)) {
            log.error(":>>> 活动:{} 没有配置:{} 任务明细", activityInfo.getId(), TaskBizType.BROADCASAT.name());
            throw new BusinessException("活动没有配置志愿福利规则明细");
        }
        if (printDomain.getTotalNum().intValue() == 0) {
            userParticipateActivityInfo.setBroadcastStatus(0);
            activityRewardRule.setBroadcastStatus(false);
        } else {
            if (printDomain.getPassedNum().compareTo(taskRule.getThreshold()) != -1) {
                userParticipateActivityInfo.setBroadcastStatus(4);
                activityRewardRule.setBroadcastStatus(true);
            } else {
                userParticipateActivityInfo.setBroadcastStatus(3);
                activityRewardRule.setBroadcastStatus(false);
            }
        }
    }

    /**
     * 获取证书领取状态
     *
     * @param userId
     * @param activityId
     * @param taskBizType
     * @return
     */
    private Integer getCaRecieveStatus(String userId, String activityId, String taskBizType) {
        List<String> statues = new ArrayList<>();
        /**
         * 状态,0:待付款,1:已付款,2:制作中,3:待发货,4:待收货,5:已收货,
         * 6:订单完成,7:订单关闭,8:售后中,9:退款中,10:部分已发货
         */
        statues.add("0");
        statues.add("9");
        statues.add("6");
        statues.add("7");
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId).and("activityId").is(activityId).and("taskBizType").is(taskBizType).and("status").nin(statues));
        boolean exist = mongoTemplate.exists(query, OrderInfo.class);
        //0:未领取,1:已经领取,未支付,2:已支付,3:未开始,4:领取结束
        if (exist) {
            return 2;
        }
        return 0;
    }

    /**
     * 获取证书领取状态
     *
     * @param userId
     * @param activityId
     * @param taskBizType
     * @return
     */
    private boolean getCaRecieveRefundStatus(String userId, String activityId, String taskBizType) {
        List<String> statues = new ArrayList<>();
        /**
         * 状态,0:待付款,1:已付款,2:制作中,3:待发货,4:待收货,5:已收货,
         * 6:订单完成,7:订单关闭,8:售后中,9:退款中,10:部分已发货
         */
        statues.add("9");
        statues.add("6");
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(userId).and("activityId").is(activityId).and("taskBizType").is(taskBizType).and("status").in(statues));
        boolean exist = mongoTemplate.exists(query, OrderInfo.class);
        //0:未领取,1:已经领取,未支付,2:已支付,3:未开始,4:领取结束
        return exist;
    }

    /**
     * 获取证书名字
     *
     * @param caName
     * @param constCaName
     * @param taskBizType
     * @param recieveRule
     * @return
     */
    private String getCaName(ActivityInfo activityInfo, String caName, String constCaName, TaskBizType taskBizType, ActivityRecieveRule recieveRule) {
        log.info(":>>> 开始获取证书名字caName:{},constCaName:{},taskBizType:{},rule:{}", caName, constCaName, taskBizType, JSON.toJSONString(recieveRule));
        if (Objects.isNull(recieveRule)) {
            log.error(":>>> 活动:{} 证书领取规则没有配置:{}", activityInfo.getName(), taskBizType);
            throw new BusinessException("证书领取规则没有配置");
        }
        String cName = "";
        switch (taskBizType) {
            case INVITE:
                log.info(":>>> 邀请证书:{}", caName);
                if (Boolean.FALSE.equals(recieveRule.getReplacedCa())) {
                    cName = caName;

                }
                if (StringUtils.isBlank(recieveRule.getReplacedCaName()) || StringUtils.isBlank(recieveRule.getReplaceByCaName())) {
                    log.error(";>>> 替换证书和被替换证书关键字错误");
                    cName = caName;
                }
                // 发双证
                if (Boolean.TRUE.equals(recieveRule.getDoubleCa())) {
                    String replacedCaName = caName.replace(recieveRule.getReplacedCaName(), recieveRule.getReplaceByCaName());
                    log.info(":>>> 活动:{} 领取规则为双证,邀请证书:{} 被替换后:{}", activityInfo.getName(), caName, replacedCaName);
                    cName = replacedCaName;
                }
                break;
            case QA:
                if (Boolean.TRUE.equals(activityInfo.getDoQaHasCa())) {
                    log.info(":>>> 活动:{} 答题:可获得证书", activityInfo.getName());
                    constCaName = caName;
                }
                if (Boolean.FALSE.equals(recieveRule.getReplacedQaCa())) {
                    cName = constCaName;
                }
                if (StringUtils.isBlank(recieveRule.getReplacedQaCaName()) || StringUtils.isBlank(recieveRule.getReplaceQaByCaName())) {
                    log.error(";>>> 替换证书和被替换证书关键字错误");
                    cName = constCaName;
                }
                if (Boolean.TRUE.equals(recieveRule.getDoubleCa())) {
                    String replacedCaName = caName.replace(recieveRule.getReplacedQaCaName(), recieveRule.getReplaceQaByCaName());
                    log.info(":>>> 活动:{} 领取规则为双证,邀请证书:{} 被替换后:{}", activityInfo.getName(), constCaName, replacedCaName);
                    cName = replacedCaName;
                }
                cName = constCaName;
                break;
            default:
                log.error(":>>> 类型错误");
                break;
        }
        return cName;

    }

    private String filterCaName(ActivityInfo activityInfo, String caName, String userId, ActivityRecieveRule recieveRule) {
        log.info(":>>> 开始过滤证书:{},{},{},{}", activityInfo.getName(), caName, userId, JSON.toJSONString(recieveRule));
        ActivityTaskInfo taskInfo = this.findActivityTaskInfo(activityInfo.getId(), TaskBizType.INVITE);
        if (Objects.isNull(taskInfo)) {
            log.error(":>>> 活动:{} 邀请任务为空", activityInfo.getName());
            return caName;
        }
        if ("暂无证书".equals(caName) || "无".equals(caName)) {
            if (Boolean.TRUE.equals(recieveRule.getPopularCa())) {
                caName = "荣誉证书";
            }
            return caName;
        }
        if (Boolean.FALSE.equals(recieveRule.getHasProvinceBand())) {
            return caName;
        }
        return caName;
    }

    private void exportSignUpUsers(Query query, String f, String exportTaskId, String activityId) {

        int counter = 0;
        HSSFWorkbook workbook = new HSSFWorkbook();
        HashMap<String, UniversityInfo> universityInfoHashMap = new HashMap<>();
        HashMap<String, CaInfo> caInfoHashMap = new HashMap<>();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            int rowNum = 1;
            int sheetNum = 1;
            //创建一个Excel表单,参数为sheet的名字
            HSSFSheet sheet = workbook.createSheet("sheet" + "-" + sheetNum);
            setCaOrderExcelTitle(workbook, sheet);
            //创建表头
//            Long count = mongoTemplate.count(query, UserParticipateActivityInfo.class);
            Long count = userUpInfoService.getJoinedCount(activityId);
            log.info(":>>>  报名信息总量:{}", count);
            Integer limit = 1000;
            Integer pages = count.intValue() / limit + 1;
            for (int i = 0; i < pages; i++) {
                log.info(":>>> 开始处理第:{} 页", i);
                query.limit(limit);
                query.skip(i * limit);
                List<UserParticipateActivityInfo> ups = mongoTemplate.find(query, UserParticipateActivityInfo.class);
                if (CollectionUtils.isEmpty(ups)) {
                    log.error(":>>> 第:{} 页数据为空:", i);
                    continue;
                }
                for (UserParticipateActivityInfo up : ups) {
                    UniversityInfo universityInfo = null;
                    if (StringUtils.isNotBlank(up.getUniversityId())) {
                        if (universityInfoHashMap.containsKey(up.getUniversityId())) {
                            universityInfo = universityInfoHashMap.get(up.getUniversityId());
                        } else {
                            Query query1 = new Query().addCriteria(Criteria.where("id").is(up.getUniversityId()));
                            universityInfo = mongoTemplate.findOne(query1, UniversityInfo.class);
                            universityInfoHashMap.put(up.getUniversityId(), universityInfo);
                        }
                    }
                    log.info(":>>> 导出行数:{}", counter);
                    if (counter != 0 && counter % 60000 == 0) {
                        //超过60000就自动创建一个sheet
                        sheetNum++;
                        sheet = workbook.createSheet("sheet-" + sheetNum);
                        setCaOrderExcelTitle(workbook, sheet);
                        //创建表头
                        //新增数据行，并且设置单元格数据
                        rowNum = 1;
                        sheetNum++;
                        log.info(":>>> 操作60000行,创建新sheet");
                    }
                    Query queryOrder = new Query().addCriteria(Criteria.where("userId").is(up.getUserId()).and("activityId").is(up.getActivityId()));
                    List<OrderInfo> contents = mongoTemplate.find(queryOrder, OrderInfo.class);
                    if (CollectionUtils.isEmpty(contents)) {
                        log.info(":>>> 活动:{} 用户:{} 订单为空:{}", up.getActivityId(), up.getUserId());
                        HSSFRow row = sheet.createRow(rowNum);
                        if (Objects.nonNull(universityInfo)) {
                            if (StringUtils.isNotBlank(universityInfo.getName())) {
                                row.createCell(7).setCellValue(universityInfo.getName());
                            }
                            if (StringUtils.isNotBlank(universityInfo.getCity())) {
                                row.createCell(31).setCellValue(universityInfo.getCity());
                            }
                            if (StringUtils.isNotBlank(universityInfo.getType())) {
                                row.createCell(32).setCellValue(universityInfo.getType());
                            }
                            if (Objects.nonNull(universityInfo.getUserCount())) {
                                row.createCell(33).setCellValue(universityInfo.getUserCount());
                            }
                            if (Objects.nonNull(universityInfo.getLevel())) {
                                row.createCell(34).setCellValue(universityInfo.getLevel());
                            }
                            if (Objects.nonNull(universityInfo.getMerged())) {
                                row.createCell(35).setCellValue(universityInfo.getMerged());
                            }
                            if (Objects.nonNull(universityInfo.getEmploymentRate())) {
                                row.createCell(36).setCellValue(universityInfo.getEmploymentRate());
                            }
                            if (Objects.nonNull(universityInfo.getEstablishedTime())) {
                                String dateNowStr = TimeUtils.parse(universityInfo.getEstablishedTime(), "yyyy-MM-dd " + "HH:mm:ss");
                                row.createCell(37).setCellValue(dateNowStr);
                            }
                            if (Objects.nonNull(universityInfo.getTags())) {
                                row.createCell(38).setCellValue(JSON.toJSONString(universityInfo.getTags()));
                            }

                        }
                        if (StringUtils.isNotBlank(up.getName())) {
                            row.createCell(8).setCellValue(up.getName());
                        }
                        if (StringUtils.isNotBlank(up.getMobile())) {
                            row.createCell(9).setCellValue(up.getMobile());
                        }
                        if (Objects.nonNull(up.getSignUpTime())) {
                            String dateNowStr = TimeUtils.parse(up.getSignUpTime(), "yyyy-MM-dd HH:mm:ss");
                            row.createCell(10).setCellValue(dateNowStr);
                        }
                        if (StringUtils.isNotBlank(up.getProvince())) {
                            row.createCell(12).setCellValue(up.getProvince());
                        }
                        if (StringUtils.isNotBlank(up.getCity())) {
                            row.createCell(13).setCellValue(up.getCity());
                        }
                        if (StringUtils.isNotBlank(up.getArea())) {
                            row.createCell(14).setCellValue(up.getArea());
                        }
                        if (StringUtils.isNotBlank(up.getAddress())) {
                            row.createCell(15).setCellValue(up.getAddress());
                        }
                        if (Objects.nonNull(up.getQaScore())) {
                            row.createCell(39).setCellValue(up.getQaScore());
                        }
                        if (Objects.nonNull(up.getPassed())) {
                            row.createCell(40).setCellValue(up.getPassed());
                        }
                        if (Objects.nonNull(up.getGrade())) {
                            row.createCell(41).setCellValue(up.getGrade());
                        }
                        if (Objects.nonNull(up.getSignUpTime())) {
                            String dateNowStr = TimeUtils.parse(up.getSignUpTime(), "yyyy-MM-dd HH:mm:ss");
                            row.createCell(42).setCellValue(dateNowStr);
                        }
                        rowNum++;
                        counter++;
                        continue;
                    }
                    for (OrderInfo content : contents) {
                        Query subOrderQuery = new Query().addCriteria(Criteria.where("orderNo").is(content.getOrderNo()));
                        List<OOrderInfo> subOrders = mongoTemplate.find(subOrderQuery, OOrderInfo.class);
                        log.info(":>>> 开始处理订单:{},子订单数量:{}", content.getOrderNo(), subOrders.size());
                        if (CollectionUtils.isNotEmpty(subOrders)) {
                            for (OOrderInfo oOrderInfo : subOrders) {
                                CaInfo caInfo = null;
                                if (StringUtils.isNotBlank(oOrderInfo.getItemInfoId())) {
                                    if (caInfoHashMap.containsKey(oOrderInfo.getItemInfoId())) {
                                        caInfo = caInfoHashMap.get(oOrderInfo.getItemInfoId());
                                    } else {
                                        caInfo = caInfoService.findOne(oOrderInfo.getItemInfoId());
                                        caInfoHashMap.put(oOrderInfo.getItemInfoId(), caInfo);
                                    }
                                }
                                log.info(":>>> 导出行数:{}", counter);
                                if (counter != 0 && counter % 60000 == 0) {
                                    //超过60000就自动创建一个sheet
                                    sheetNum++;
                                    sheet = workbook.createSheet("sheet-" + sheetNum);
                                    setCaOrderExcelTitle(workbook, sheet);
                                    //创建表头
                                    //新增数据行，并且设置单元格数据
                                    rowNum = 1;
                                    sheetNum++;
                                    log.info(":>>> 操作60000行,创建新sheet");
                                }
                                HSSFRow row = sheet.createRow(rowNum);
                                if (Objects.nonNull(oOrderInfo) && StringUtils.isNotBlank(oOrderInfo.getItemTitle())) {
                                    String[] splitAddress = oOrderInfo.getItemTitle().split("，");
                                    if (splitAddress.length == 3) {
                                        row.createCell(0).setCellValue(splitAddress[0]);
                                        row.createCell(11).setCellValue(splitAddress[2]);
                                        row.createCell(27).setCellValue(splitAddress[1]);

                                    } else if (splitAddress.length == 2) {
                                        row.createCell(0).setCellValue(splitAddress[0]);
                                        row.createCell(11).setCellValue(splitAddress[1]);
                                    }
                                }
                                // 订单编号
                                if (StringUtils.isNotBlank(content.getOrderNo())) {
                                    row.createCell(2).setCellValue(content.getOrderNo());
                                }
                                // 订单状态
                                String caStatusStr = this.getOrderStatusStr(content.getStatus());
                                log.info(":>>> 订单状态:{}", caStatusStr);
                                row.createCell(3).setCellValue(caStatusStr);
                                if (StringUtils.isNotBlank(content.getLogisticsCompany())) {
                                    row.createCell(4).setCellValue(content.getLogisticsCompany());
                                }
                                if (StringUtils.isNotBlank(content.getLogisticsNo())) {
                                    row.createCell(5).setCellValue(content.getLogisticsNo());
                                }
                                if (StringUtils.isNotBlank(content.getActivityId())) {
                                    Query queryA = new Query().addCriteria(Criteria.where("id").is(content.getActivityId()));
                                    ActivityInfo activityInfo = mongoTemplate.findOne(queryA, ActivityInfo.class);
                                    if (Objects.nonNull(activityInfo) && StringUtils.isNotBlank(activityInfo.getName())) {
                                        row.createCell(6).setCellValue(activityInfo.getName());
                                    }
                                }
                                if (StringUtils.isNotBlank(content.getUniversityName())) {
                                    row.createCell(7).setCellValue(content.getUniversityName());
                                }
                                if (StringUtils.isNotBlank(content.getName())) {
                                    row.createCell(8).setCellValue(content.getName());
                                }
                                if (StringUtils.isNotBlank(content.getMobile())) {
                                    row.createCell(9).setCellValue(content.getMobile());
                                }
                                if (Objects.nonNull(content.getPayTime())) {
                                    String dateNowStr = TimeUtils.parse(content.getPayTime(), "yyyy-MM-dd HH:mm:ss");
                                    row.createCell(10).setCellValue(dateNowStr);
                                }
                                if (StringUtils.isNotBlank(content.getProvince())) {
                                    row.createCell(12).setCellValue(content.getProvince());
                                }
                                if (StringUtils.isNotBlank(content.getCity())) {
                                    row.createCell(13).setCellValue(content.getCity());
                                }
                                if (StringUtils.isNotBlank(content.getArea())) {
                                    row.createCell(14).setCellValue(content.getArea());
                                }
                                if (StringUtils.isNotBlank(content.getAddress())) {
                                    row.createCell(15).setCellValue(content.getAddress());
                                }
                                if (Objects.nonNull(oOrderInfo.getSalePrice())) {
                                    row.createCell(16).setCellValue(oOrderInfo.getSalePrice() / 100);
                                }
                                if (Objects.nonNull(content.getTransactionId())) {
                                    row.createCell(17).setCellValue(content.getTransactionId());
                                }
                                if (Objects.nonNull(content.getRefundFee())) {
                                    row.createCell(18).setCellValue(content.getRefundFee());
                                }
                                if (StringUtils.isNotBlank(content.getTagsSearchStr())) {
                                    row.createCell(20).setCellValue(content.getTagsSearchStr());
                                }
                                if (StringUtils.isNotBlank(content.getId())) {
                                    row.createCell(21).setCellValue(content.getId());
                                }
                                if (StringUtils.isNotBlank(content.getPlatform())) {
                                    row.createCell(22).setCellValue(content.getPlatform());
                                }
                                log.info(":>>> 大学ID:{}", content.getUniversityId());
                                if (StringUtils.isNotBlank(content.getUniversityId())) {

                                    if (universityInfoHashMap.containsKey(content.getUniversityId())) {
                                        row.createCell(23).setCellValue(universityInfoHashMap.get(content.getUniversityId()).getName());
                                    } else {
                                        Query query1 = new Query().addCriteria(Criteria.where("id").is(content.getUniversityId()));
                                        UniversityInfo universityInfo1 = mongoTemplate.findOne(query1, UniversityInfo.class);
                                        if (Objects.nonNull(universityInfo1)) {
                                            row.createCell(23).setCellValue(universityInfo1.getName());
                                            universityInfoHashMap.put(content.getUniversityId(), universityInfo);
                                        }
                                    }
                                }
                                if (Objects.nonNull(oOrderInfo) && StringUtils.isNotBlank(oOrderInfo.getGift())) {
                                    String g = oOrderInfo.getGift().replace("<P>", "");
                                    g = g.replace("</p>", "");
                                    row.createCell(24).setCellValue(g);
                                }
                                if (Objects.nonNull(content.getTotalFee())) {
                                    row.createCell(25).setCellValue(content.getTotalFee() / 100);
                                }
                                if (subOrders.size() > 1) {
                                    row.createCell(26).setCellValue("是");
                                } else {
                                    row.createCell(26).setCellValue("否");
                                }
                                // 2021-05-28 00:36:07 之后版本更新了
                                if (Objects.nonNull(caInfo) && content.getCreatedTime().after(new Date(1622133367000L))) {

                                    if (StringUtils.isNotBlank(caInfo.getLevel())) {
                                        row.createCell(27).setCellValue(caInfo.getLevel());
                                    }
                                    if (StringUtils.isNotBlank(caInfo.getEdition())) {
                                        row.createCell(11).setCellValue(caInfo.getEdition());
                                    }
                                    if (StringUtils.isNotBlank(caInfo.getName())) {
                                        row.createCell(0).setCellValue(caInfo.getName());
                                    }

                                }
                                if (Objects.nonNull(content.getCaPrintName())) {
                                    row.createCell(28).setCellValue(content.getCaPrintName());
                                }
                                if (StringUtils.isNotBlank(content.getActivityId()) || StringUtils.isNotBlank(content.getAccountInfoId())) {
                                    Query queryUp = new Query().addCriteria(Criteria.where("userId").is(content.getAccountInfoId()).and("joined").is(Boolean.TRUE));
                                    Long count1 = mongoTemplate.count(queryUp, UserParticipateActivityInfo.class);
                                    if (Objects.nonNull(count1)) {
                                        row.createCell(29).setCellValue(count1.intValue());
                                    }
                                    Query queryInvite = new Query().addCriteria(Criteria.where("invitedByUserId").is(content.getAccountInfoId()).and("activityId").is(content.getActivityId()));
                                    Long countInvite = mongoTemplate.count(queryInvite, UserInviteRecord.class);
                                    if (Objects.nonNull(countInvite)) {
                                        row.createCell(30).setCellValue(countInvite.intValue());
                                    }
                                }
                                if (Objects.nonNull(universityInfo)) {
                                    if (StringUtils.isNotBlank(universityInfo.getCity())) {
                                        row.createCell(31).setCellValue(universityInfo.getCity());
                                    }
                                    if (StringUtils.isNotBlank(universityInfo.getType())) {
                                        row.createCell(32).setCellValue(universityInfo.getType());
                                    }
                                    if (Objects.nonNull(universityInfo.getUserCount())) {
                                        row.createCell(33).setCellValue(universityInfo.getUserCount());
                                    }
                                    if (Objects.nonNull(universityInfo.getLevel())) {
                                        row.createCell(34).setCellValue(universityInfo.getLevel());
                                    }
                                    if (Objects.nonNull(universityInfo.getMerged())) {
                                        row.createCell(35).setCellValue(universityInfo.getMerged());
                                    }
                                    if (Objects.nonNull(universityInfo.getEmploymentRate())) {
                                        row.createCell(36).setCellValue(universityInfo.getEmploymentRate());
                                    }
                                    if (Objects.nonNull(universityInfo.getEstablishedTime())) {
                                        String dateNowStr = TimeUtils.parse(universityInfo.getEstablishedTime(), "yyyy-MM-dd HH:mm:ss");
                                        row.createCell(37).setCellValue(dateNowStr);
                                    }
                                    if (Objects.nonNull(universityInfo.getTags())) {
                                        row.createCell(38).setCellValue(JSON.toJSONString(universityInfo.getTags()));
                                    }

                                }
                                if (Objects.nonNull(up.getQaScore())) {
                                    row.createCell(39).setCellValue(up.getQaScore());
                                }
                                if (Objects.nonNull(up.getPassed())) {
                                    row.createCell(40).setCellValue(up.getPassed());
                                }
                                if (Objects.nonNull(up.getGrade())) {
                                    row.createCell(41).setCellValue(up.getGrade());
                                }
                                if (Objects.nonNull(up.getSignUpTime())) {
                                    String dateNowStr = TimeUtils.parse(up.getSignUpTime(), "yyyy-MM-dd HH:mm:ss");
                                    row.createCell(42).setCellValue(dateNowStr);
                                }
                                rowNum++;
                            }
                        }
                        counter++;
                    }

                    rowNum++;
                    counter++;
                }
            }
            //将excel写入到输出流中
            log.info(":>>> flush:{} 行", rowNum);
            OutputStream outputStream = new FileOutputStream(fileExportPath + f);
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            log.info(":>>> 写文件到本地然后读:{}", f);
            File file = new File(fileExportPath + f);
            InputStream in = new FileInputStream(file);
            String url = fileService.uploadFile(in, f);
            Query queryTask = new Query().addCriteria(Criteria.where("id").is(exportTaskId));
            Update update = new Update();
            update.set("url", url);
            update.set("status", 1);
            update.set("updatedTime", new Date());
            UpdateResult updateResult = mongoTemplate.updateFirst(queryTask, update, FileExportTask.class);
            log.info(":>>> 更新任务:{},状态:{}", exportTaskId, updateResult.getModifiedCount() > 0 ? true : false);
            in.close();
            log.info(":>>> 所有活动参与员导出,关闭文件流");
        } catch (Exception e) {
            log.error(":>>> 所有活动参与员导出错误:{}", e);
        }
    }


    /**
     * 计算答题得分
     *
     * @param req
     * @return
     */
    @Override
    public Double computeQaScore(UserDoQaVO req) {
        //获取用户提交答题信息ID
        List<String> userSubmitQuestionIdList = req.getQas().stream().map(activityQaInfoVO -> activityQaInfoVO.getQuestion().getId()).collect(Collectors.toList());
        // List<ActivityQuestionInfo> userAnswersQuestionInfoList = qaCommitCommand.getUserAnswersQuestionInfoList();
        //获取用户选择题提交到库中查找答题信息-找到正确答案
        Query query = new Query();
        query.addCriteria(Criteria.where("activityQaInfoId").is(req.getActivityQaInfoId()));
        query.addCriteria(Criteria.where("id").in(userSubmitQuestionIdList));
        List<ActivityQuestionInfo> questionInfoList = this.mongoTemplate.find(query, ActivityQuestionInfo.class);
        if (CollectionUtils.isEmpty(questionInfoList)) {
            throw new BusinessException("未找到答题信息");
        }
        List<ActivityQuestionInfo> userAnswersQuestionInfoList = req.getQas().stream().map(activityQaInfoVO -> {
            ActivityQuestionInfo userCommitQuestion = activityQaInfoVO.getQuestion();
            //用户选择中了才提交
            List<ActivityAnswerInfo> userQaCommitAnswerList = activityQaInfoVO.getAnswers().stream().filter(userQaCommitAnswer -> userCommitQuestion.getId().equals(userQaCommitAnswer.getActivityQuestionId()) && userQaCommitAnswer.getChoiced()).map(userQaCommitAnswer -> {
                ActivityAnswerInfo activityAnswerInfo = new ActivityAnswerInfo();
                BeanUtils.copyProperties(userQaCommitAnswer, activityAnswerInfo);
                activityAnswerInfo.setId(userQaCommitAnswer.getId());
                activityAnswerInfo.setAnswered(userQaCommitAnswer.getChoiced());
                return activityAnswerInfo;
            }).collect(Collectors.toList());
            userCommitQuestion.setAnswerInfos(userQaCommitAnswerList);
            return userCommitQuestion;
        }).collect(Collectors.toList());
        QaInfoScoreResponse qaInfoScore = competitionQaInfoService.getQaScore(req.getUserId(), req.getActivityQaInfoId(), questionInfoList, userAnswersQuestionInfoList);
        log.info("用户-> {}参与活动-> {}答题得分-> {}", req.getUserId(), req.getActivityId(), qaInfoScore.getQaScore());
        qaInfoScore.getUserAnswersRightQuestionInfoList().clear();
        qaInfoScore.getUserAnswersErrorQuestionInfoList().clear();
        return qaInfoScore.getQaScore();
    }

    private MultiQaRes buildMultiQaRes(UserQaInfo userQaInfo, ActivityQaInfo activityQaInfo, Integer totalQa) {
        final String userId = userQaInfo.getUserId();
        final String activityId = userQaInfo.getActivityId();
        MultiQaRes multiQaRes = new MultiQaRes();
        multiQaRes.setActivityId(activityId);
        multiQaRes.setNo(activityQaInfo.getNo());
        multiQaRes.setNextNo(activityQaInfo.getNo() + 1);
        multiQaRes.setCaName(userQaInfo.getCaName());
        multiQaRes.setPassed(userQaInfo.getPassed());
        multiQaRes.setScore(userQaInfo.getCurrentQaScore());
        multiQaRes.setNextQaName(activityQaInfo.getNextQaName());
        multiQaRes.setReTryQaNum(userQaInfo.getReTryQaNum() == null ? 0 : userQaInfo.getReTryQaNum());
        if (totalQa.intValue() == userQaInfo.getNo() || "无".equals(activityQaInfo.getNextQaName())) {
            multiQaRes.setHasNextQa(false);
        } else {
            multiQaRes.setHasNextQa(true);
        }
        if ("暂无证书".equals(userQaInfo.getCaName()) && Boolean.FALSE.equals(multiQaRes.getPassed())) {
            multiQaRes.setTips("再接再厉!");
        } else {
            if (multiQaRes.getHasNextQa()) {
                multiQaRes.setTips("获得" + userQaInfo.getCaName() + "并解锁" + multiQaRes.getNextQaName());
            } else {
                multiQaRes.setTips("获得" + userQaInfo.getCaName());

            }
        }
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId));
        UserParticipateActivityInfo userParticipateActivityInfo = this.mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        Update update = new Update();
        update.set("contestCaName", userQaInfo.getCaName());
        update.set("updatedTime", new Date());
        if (Boolean.TRUE.equals(userQaInfo.getPassed())) {
            if (activityQaInfo.getNo().intValue() < 3) {
                update.set("currentQa", activityQaInfo.getNo() + 1);
                log.info(":>>> 用户:{},活动答题:{} 当前阶段:{}", userId, activityId, activityQaInfo.getNo() + 1);
            } else {
                update.set("currentQa", activityQaInfo.getNo());
                log.info(":>>> 用户:{},活动答题:{} 当前阶段:{}", userId, activityId, activityQaInfo.getNo());
            }
        } else {
            update.set("currentQa", activityQaInfo.getNo());
            log.info(":>>> 用户:{},活动答题:{} 当前阶段:{}", userId, activityId, activityQaInfo.getNo());
        }
        //
        update.set("qaScore", userQaInfo.getQaScore());
        update.set("passQaScore", activityQaInfo.getPassQaScore());
        if (Objects.nonNull(userParticipateActivityInfo) && !userParticipateActivityInfo.getAccumulateQ()) {
            update.set("accumulateQ", userQaInfo.getAccumulateQ());
            update.set("passed", userQaInfo.getPassed());
        }
        if (userQaInfo.getNo() == 1) {
            update.set("reTryQaNum", userQaInfo.getReTryQaNum());
        }
        update.set("currentQaScore", userQaInfo.getCurrentQaScore());
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, UserParticipateActivityInfo.class);
        log.info(":>>> 更新用户:{} 活动答题,{},证书名:{},结果为:{}", userId, activityId, userQaInfo.getCaName(), updateResult.getModifiedCount() > 0 ? true : false);
        log.info(":>>> 结束提交多级答题:{}", JSON.toJSONString(multiQaRes));
        return multiQaRes;
    }

    private String getOrderStatusStr(String caStatus) {
        String status = " ";
        if (Objects.nonNull(caStatus)) {

            switch (caStatus) {
                case "0":
                    status = "待付款";
                    break;
                case "1":
                    status = "已付款";
                    break;
                case "2":
                    status = "制作中";
                    break;
                case "3":
                    status = "待发货";
                    break;
                case "4":
                    status = "待收货";
                    break;
                case "5":
                    status = "已收货";
                    break;
                case "6":
                    status = "订单完成";
                    break;
                case "7":
                    status = "订单关闭";
                    break;
                case "8":
                    status = "售后中";
                    break;
                case "9":
                    status = "退款中";
                    break;
                case "10":
                    status = "待返货";
                    break;
                case "11":
                    status = "返货中";
                    break;
                case "12":
                    status = "退款完成";
                    break;
                default:
                    break;
            }
        }
        return status;
    }

    private void setCaOrderExcelTitle(HSSFWorkbook workbook, HSSFSheet sheet) {
        HSSFRow row = sheet.createRow(0);
        //设置列宽，setColumnWidth的第二个参数要乘以256，这个参数的单位是1/256个字符宽度
        sheet.setColumnWidth(0, 10 * 256);
        sheet.setColumnWidth(1, 20 * 256);
        sheet.setColumnWidth(2, 20 * 256);
        sheet.setColumnWidth(3, 20 * 256);

        //设置为居中加粗
        HSSFCellStyle style = workbook.createCellStyle();
        HSSFFont font = workbook.createFont();
        style.setFont(font);

        HSSFCell cell;
        cell = row.createCell(0);
        cell.setCellValue("证书名");
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue("证书编号");
        cell.setCellStyle(style);

        cell = row.createCell(2);
        cell.setCellValue("订单编号");
        cell.setCellStyle(style);

        cell = row.createCell(3);
        cell.setCellValue("订单状态");
        cell.setCellStyle(style);

        cell = row.createCell(4);
        cell.setCellValue("物流公司");
        cell.setCellStyle(style);

        cell = row.createCell(5);
        cell.setCellValue("物流编号");
        cell.setCellStyle(style);

        cell = row.createCell(6);
        cell.setCellValue("活动名称");
        cell.setCellStyle(style);

        cell = row.createCell(7);
        cell.setCellValue("大学");
        cell.setCellStyle(style);

        cell = row.createCell(8);
        cell.setCellValue("姓名");
        cell.setCellStyle(style);

        cell = row.createCell(9);
        cell.setCellValue("电话");
        cell.setCellStyle(style);

        cell = row.createCell(10);
        cell.setCellValue("支付时间");
        cell.setCellStyle(style);

        cell = row.createCell(11);
        cell.setCellValue("证书材质");
        cell.setCellStyle(style);
        cell = row.createCell(12);
        cell.setCellValue("省");
        cell.setCellStyle(style);
        cell = row.createCell(13);
        cell.setCellValue("市");
        cell.setCellStyle(style);
        cell = row.createCell(14);
        cell.setCellValue("区");
        cell.setCellStyle(style);
        cell = row.createCell(15);
        cell.setCellValue("地址");
        cell.setCellStyle(style);
        cell = row.createCell(16);
        cell.setCellValue("单价");
        cell.setCellStyle(style);
        cell = row.createCell(17);
        cell.setCellValue("微信交易号");
        cell.setCellStyle(style);
        cell = row.createCell(18);
        cell.setCellValue("退款金额");
        cell.setCellStyle(style);
        cell = row.createCell(19);
        cell.setCellValue("退款时间");
        cell.setCellStyle(style);
        cell = row.createCell(20);
        cell.setCellValue("订单备注");
        cell.setCellStyle(style);
        cell = row.createCell(21);
        cell.setCellValue("订单标示");
        cell.setCellStyle(style);
        cell = row.createCell(22);
        cell.setCellValue("平台");
        cell.setCellStyle(style);
        cell = row.createCell(23);
        cell.setCellValue("大学");
        cell.setCellStyle(style);
        cell = row.createCell(24);
        cell.setCellValue("礼品");
        cell.setCellStyle(style);
        cell = row.createCell(25);
        cell.setCellValue("订单总价");
        cell.setCellStyle(style);
        cell = row.createCell(26);
        cell.setCellValue("是否需要合单");
        cell.setCellStyle(style);
        cell = row.createCell(27);
        cell.setCellValue("等级");
        cell.setCellStyle(style);
        cell = row.createCell(28);
        cell.setCellValue("证书打印名字");
        cell.setCellStyle(style);
        cell = row.createCell(29);
        cell.setCellValue("参与活动次数");
        cell.setCellStyle(style);
        cell = row.createCell(30);
        cell.setCellValue("邀请人数");
        cell.setCellStyle(style);
        cell = row.createCell(31);
        cell.setCellValue("学校城市");
        cell.setCellStyle(style);
        cell = row.createCell(32);
        cell.setCellValue("学校类型");
        cell.setCellStyle(style);
        cell = row.createCell(33);
        cell.setCellValue("学校人数");
        cell.setCellStyle(style);
        cell = row.createCell(34);
        cell.setCellValue("学校等级");
        cell.setCellStyle(style);
        cell = row.createCell(35);
        cell.setCellValue("是否合并");
        cell.setCellStyle(style);
        cell = row.createCell(36);
        cell.setCellValue("就业率");
        cell.setCellStyle(style);
        cell = row.createCell(37);
        cell.setCellValue("成立时间");
        cell.setCellStyle(style);
        cell = row.createCell(38);
        cell.setCellValue("学校标签");
        cell.setCellStyle(style);
        cell = row.createCell(39);
        cell.setCellValue("答题分数");
        cell.setCellStyle(style);
        cell = row.createCell(40);
        cell.setCellValue("是否通过");
        cell.setCellStyle(style);
        cell = row.createCell(41);
        cell.setCellValue("年级");
        cell.setCellStyle(style);
        cell = row.createCell(42);
        cell.setCellValue("报名时间");
        cell.setCellStyle(style);

    }

    /**
     * 累加答题贡献值
     *
     * @param activityInfo
     * @param userId
     * @param userPO
     */
    private void accumulateQaQ(ActivityInfo activityInfo, String userId, UserPO userPO) {
        log.info(":>>> 开始累加:{},用户:{},积分值", activityInfo.getId(), userId);
        ActivityTaskRule taskRule = activityTaskRuleService.find(activityInfo.getId(), TaskBizType.QA.name());
        log.info(":>>> 活动:{},任务:{},配置的规则:{}", activityInfo.getId(), TaskBizType.QA.name(), JSON.toJSONString(taskRule));
        if (Objects.isNull(taskRule)) {
            log.error(":>>> 活动:{} 答题规则配置为空", activityInfo.getId());
            return;
        }
        ActivityTaskInfo taskInfo = this.findActivityTaskInfo(activityInfo.getId(), TaskBizType.INVITE);
        //更新用户 贡献值
        taskInfo.setPoints(taskRule.getPoints());//重置 贡献值
        userActivityTaskRankingService.saveQuantity(userPO, taskInfo, TaskBizType.QA);
    }

    /**
     * 获取学校竞赛总榜数量
     *
     * @param activityId
     * @param taskId
     * @return
     */
    private Long getUniversityContestRankingCount(String activityId, String taskId) {
        String key = RedisKeyUtil.getUniversityContestRankingCountKey(activityId, taskId);
        Object o = redisTemplate.opsForValue().get(key);
        if (Objects.isNull(o)) {
            Long count = 100L;
            //如果为null设置默认值
            redisTemplate.opsForValue().set(key, count+"", 1, TimeUnit.HOURS);
            return count;
        }
        return (Long) o;
    }

    private Long setOrgRankingCount(String activityId, String taskId, Long c) {
        String key = this.getOrgRankingCountKey(activityId, taskId);
        redisTemplate.opsForValue().set(key, c+"", 4, TimeUnit.HOURS);
        Object o = redisTemplate.opsForValue().get(key);
        if (Objects.isNull(o)) {
            return null;
        }
        return (Long) o;
    }

    private Long getOrgRankingCount(String activityId, String taskId) {
        String key = this.getOrgRankingCountKey(activityId, taskId);
        Object o = redisTemplate.opsForValue().get(key);
        if (Objects.isNull(o)) {
            return null;
        }
        return (Long) o;
    }

    protected String getOrgRankingCountKey(String activityId, String taskId) {
        return String.format(ORG_RANK_LIST_KEY, activityId, taskId);
    }


    /**
     * 生成证书
     *
     * @param activityId
     * @param activityName
     */
    @Override
    public void generateUserCa(String activityId, String activityName, UserPO userPO, String platform) {
        log.info(":>>> 开始生成志愿者证书:{},{},{}", activityId, userPO.getId(), platform);
        String userId = userPO.getId();
        UserCa userCa = new UserCa();
        ActivityInfo activityInfo = this.findOne(activityId);
        String keyWord = activityInfo.getCaMatchKeyWords().get("invite");
        if (StringUtils.isBlank(keyWord)) {
            log.error(":>>> 活动:{} 没有配置证书匹配关键字", activityId);
            return;
        }
        UserParticipateActivityInfo up = query(userPO, activityId, true, platform);
        if (Objects.isNull(up)) {
            log.info(":>>> 用户:{} 活动:{} 报名信息为空", userPO.getId(), activityId);
            return;
        }
        ActivityTaskDataDomain domain = up.getDatas().get("INVITE");
        log.info(":>>> 用户:{} 活动:{} 证书等级信息:{}", userId, activityId, JSON.toJSONString(domain));
        if (Objects.isNull(domain) || "暂无证书".equals(domain.getCaName())) {
            log.error(":>>> 用户:{} 活动:{} 获取暂无证书", userId, activityId);
            return;
        }
        //获取证书信息
        String matchesRegexKey = String.format(".*(%s).*", keyWord);
        log.info(":>>> 活动:{} 证书匹配表达式:{}", activityId, matchesRegexKey);
        String finalMatchesRegexKey = matchesRegexKey;
        List<CertificateActivityConfig> certificateActivityConfigList = certificateActivityConfigService.findByActivityId(activityId);
        String caType = "";
        //新数据兼容
        Optional<CertificateActivityConfig> certificateActivityConfigOptional = certificateActivityConfigList.stream().filter(certificateActivityConfig -> certificateActivityConfig.getCertificateName().matches(finalMatchesRegexKey) || certificateActivityConfig.getCaType().matches(finalMatchesRegexKey)).findAny();
        if (certificateActivityConfigOptional.isPresent()) {
            CertificateActivityConfig certificateActivityConfig = certificateActivityConfigOptional.get();
            userCa.setCertificateActivityConfigId(certificateActivityConfig.getId());
            userCa.setCaType(certificateActivityConfig.getCaType());
            caType = certificateActivityConfig.getCaType();
            userCa.setCertificateName(certificateActivityConfig.getCertificateName());
        }
        UserCa userCa1 = userCaService.findByUserIdAndCaTypeAndCaLevel(userId, caType, domain.getCaName(), activityId);
        if (Objects.nonNull(userCa1)) {
            log.info(":>>> 用户:{},类型:{}，等级:{},活动:{} 证书已经存在已经存在", userCa, caType, domain.getCaName(), activityId);
            return;
        }
        userCa.setCaLevel(domain.getCaName());
        userCa.setActivityId(activityId);
        userCa.setMoneyType("3");
        userCa.setActivityName(activityName);
        userCa.setTaskBizType("invite");
        userCa.setUniversityId(up.getUniversityId());
        userCa.setUniversityName(up.getUniversityName());
        userCa.setName(up.getName());
        userCa.setMobile(up.getMobile());
        userCa.setGrade(up.getGrade());
        userCa.setUserId(userId);
        userCa.setScore(domain.getQ());
        userCa.setPlatform(userPO.getCurrentPlatform());
        userCa.setAppId(userPO.getAppId());
        //生成用户证书信息
        log.info(":>>> 生成用户:{} 活动:{} 志愿者证书:{}", userCa, activityId, JSON.toJSONString(userCa));
        userCaService.create(userCa);
    }

    public Long getJoinNum(String activityId, Long initJoinNum, boolean query) {
        if (query) {
            Long total = initJoinNum;
            total += userUpInfoService.getJoinedCount(activityId);
            total += userActivityService.getActivityRandomNum(activityId);
            total = total / 2;
            return total;
        }
        return 0L;
    }

    /**
     * 获取视频观看数量
     *
     * @param activityId
     * @param initJoinNum
     * @param query
     * @return
     */
    public Long getViewNum(String activityId, Long initJoinNum, boolean query) {
        if (query) {
            Long total = initJoinNum;
            total += userUpInfoService.getJoinedCount(activityId);
            total += userActivityService.getActivityViewRandomNum(activityId);
            return total;
        }
        return 0L;
    }

    private String setAuthModeForQrCode(String qrCode, String authMode) {
        if (StringUtils.isBlank(qrCode) || StringUtils.isBlank(authMode)) {
            return qrCode;
        }
        if ("sms".equals(authMode)) {
            qrCode = qrCode + "&authorizeMode=" + authMode;
            return qrCode;
        }
        return qrCode;
    }
}
